package com.kitty.game.fight.service;

import com.kitty.common.model.Pos;
import com.kitty.common.utils.SpringUtils;
import com.kitty.common.utils.Pair;
import com.kitty.common.utils.PositionUtils;
import com.kitty.common.core.SchedulerManager;
import com.kitty.game.ServerService;
import com.kitty.game.activity.service.other.SuperBossHandler;
import com.kitty.game.activity.service.shidao.ShiDaoHandler;
import com.kitty.game.artifact.ArtifactService;
import com.kitty.game.attribute.AttrService;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.base.service.BagService;
import com.kitty.game.config.GuardSet;
import com.kitty.game.config.PetSet;
import com.kitty.game.config.Xing;
import com.kitty.game.confirm.model.AvoidMonsterConfirm;
import com.kitty.game.confirm.model.PetFightConfirm;
import com.kitty.game.drop.DropDataPool;
import com.kitty.game.drop.model.product.DropSet;
import com.kitty.game.drop.model.product.FightDropSet;
import com.kitty.game.drop.newservice.NewDropService;
import com.kitty.game.drop.service.DropService;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespGeneralNotify;
import com.kitty.game.enter.RespUpdate;
import com.kitty.game.enter.TitleInfo;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.fight.SkillConst;
import com.kitty.game.fight.artifact.active.ArtifactSkillProcessor;
import com.kitty.game.fight.artifact.passive.ArtifactType;
import com.kitty.game.fight.bean.*;
import com.kitty.game.fight.book.BookSkillProcessor;
import com.kitty.game.fight.factory.FightFactory;
import com.kitty.game.fight.item.FightItemHandler;
import com.kitty.game.fight.message.*;
import com.kitty.game.fight.message.vo.CombatAddObject;
import com.kitty.game.fight.message.vo.FightMember;
import com.kitty.game.fight.message.vo.RefreshPet;
import com.kitty.game.fight.message.vo.SkillGroup;
import com.kitty.game.fight.model.BattleUnit;
import com.kitty.game.fight.model.SkillAction;
import com.kitty.game.fight.model.SkillAutoPicker;
import com.kitty.game.fight.reward.FightRewardHandler;
import com.kitty.game.fight.task.AutoChuShouTask;
import com.kitty.game.fight.task.FightingTask;
import com.kitty.game.fight.util.FightAction;
import com.kitty.game.fight.util.FightMessageUtil;
import com.kitty.game.fight.util.FightRateUtil;
import com.kitty.game.fight.util.SkillTargetPicker;
import com.kitty.game.fight.zhenfa.ZhenFaInfo;
import com.kitty.game.fight.zhenfa.ZhenFaService;
import com.kitty.game.guard.model.Guard;
import com.kitty.game.guard.service.GuardService;
import com.kitty.game.i18n.I18nId;
import com.kitty.game.i18n.I18nIdDataPool;
import com.kitty.game.pet.PetDataPool;
import com.kitty.game.pet.bean.PetObject;
import com.kitty.game.pet.message.RespPetInfo;
import com.kitty.game.pet.message.RespSetCurrentPet;
import com.kitty.game.pet.message.vo.PetInfo;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.model.PetBook;
import com.kitty.game.pet.service.BookService;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.petBook.RespFightBook;
import com.kitty.game.role.message.ReqGeneralNotify;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.skill.message.RespUpdateSkill;
import com.kitty.game.skill.message.vo.SkillInfo;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.skill.service.SkillService;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.utils.*;
import com.kitty.game.waiguan.CustomFasionIcon;
import com.kitty.listener.EventDispatcher;
import com.kitty.listener.EventType;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.listener.event.LoginEvent;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.session.SessionManager;
import com.kitty.mina.session.SessionProperties;
import com.kitty.mina.task.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.session.IoSession;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.kitty.game.utils.Const.CLIENT_INACTIVE;
import static com.kitty.game.utils.StatusConst.*;


@Service
@Slf4j
public class FightService {
    @Autowired
    NewDropService newDropService;
    @Autowired
    DropService dropService;
    @Autowired
    BroadcastService broadcastService;
    @Autowired
    CountService countService;
    @Autowired
    RoleService roleService;
    @Autowired
    TeamService teamService;
    @Autowired
    PetService petService;
    @Autowired
    SkillService skillService;
    @Autowired
    EquipService equipService;
    @Autowired
    ArtifactService artifactService;
    @Autowired
    GuardService guardService;
    @Autowired
    AttrService attrService;
    @Autowired
    BookService bookService;
    @Autowired
    FightMessageService fightMessageService;
    @Autowired
    FightExecutorService fightExecutorService;

    /**
     * 登录的事件
     */
//    @EventHandler(EventType.LOGIN)
    public void handleLoginEvent(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();
       enterFight(role);

    }

    /**
     * 重连战斗 todo 只需要在登录的时候检测是否需要重连战斗
     *
     * @param role
     */
    private void enterFight(Role role) {
        Fight fight = getFightByRoleId(role.getRoleId());
        if (fight == null || fight.isOver()) {
            return;
        }
        FightObject roleObject = fight.queryFightObject(role.getRoleId());
        if (roleObject == null) {
            return;
        }
        fightExecutorService.addFightTask(fight, () -> SpringUtils.getBean(FightService.class).nextRound(role, fight));
        List<CustomFasionIcon> customIconListA = fight.getCustomIconListA();
        List<CustomFasionIcon> customIconListB = fight.getCustomIconListB();

        /** 重连友方 */
        RespCombatFriends_CL respFightMemberA = new RespCombatFriends_CL();
        List<FightMember> fightMemberA = getFightMemberList(fight.getListA(), customIconListA);
        /** 重连敌方 */
        RespCombatOpponets_CL respFightMemberB = new RespCombatOpponets_CL();
        List<FightMember> fightMemberB = getFightMemberList(fight.getListB(), customIconListB);

        roleService.sendAutoSet(role);
        /** 进入战斗 */
        MessagePusher.pushMessage(role, fightMessageService.startCombat(role));

        /** 刷新宠物 */
        if (roleObject.getFightPetId() >= 1) {
            RespRefreshPetList respRefreshPetList = new RespRefreshPetList();
            RefreshPet refreshPet = new RefreshPet();
            ArrayList<RefreshPet> refreshPets = new ArrayList<>();
            refreshPets.add(refreshPet);
            refreshPet.setPetId(roleObject.getFightPetId());
            respRefreshPetList.setPetList(refreshPets);
            MessagePusher.pushMessage(role, respRefreshPetList);
        }
        /** 发送站位包 */
        if (roleObject.isASide()) {
            respFightMemberA.setList(fightMemberA);
            respFightMemberB.setList(fightMemberB);
            respFightMemberA.setCustomIconList(customIconListA);
            respFightMemberB.setCustomIconList(customIconListB);
        } else {
            respFightMemberB.setList(fightMemberA);
            respFightMemberA.setList(fightMemberB);
            respFightMemberB.setCustomIconList(customIconListA);
            respFightMemberA.setCustomIconList(customIconListB);
        }
        MessagePusher.pushMessage(role, respFightMemberB);
        MessagePusher.pushMessage(role, respFightMemberA);

        /** 检测buff状态和死亡状态 */
        RespInitStatus respInitStatus = new RespInitStatus();
        respInitStatus.setList(new ArrayList<>());
        fight.getAllFightObjects().forEach(
                fightObject -> respInitStatus.getList().add(fightMessageService.checkCombatStatus(fightObject)));
        MessagePusher.pushMessage(role, respInitStatus);

        FightMessageUtil.sendFightPackage(fight, fightMessageService.charOffline(role.getRoleId(), 0));
        broadcastService.sendTitleInfo(role);
    }

    /**
     * 获得站位封包
     */
    public List<FightMember> getFightMemberList(List<FightObject> fightObjs,
                                                 List<CustomFasionIcon> customFasionIcons) {
        ArrayList<FightMember> members = new ArrayList<>();
        for (FightObject fightObject : fightObjs) {
            FightMember fightMember = null;
            if (fightObject.isPlayer()) {
                fightMember = fightObject.asFightMember(customFasionIcons);
            } else {
                fightMember = fightObject.asFightMember();
            }
            if (fightMember != null) {
                members.add(fightMember);
            }
        }
        return members;
    }

    /**
     * 战斗中添加宠物到战场
     */
    public Pair<Message, Message> addPet2Fight(int hostId, Pet pet, Fight fight, int pos, boolean supply) {
        FightObject hostObject = fight.queryFightObject(hostId);
        SpringUtils.getFightService().fullHpAndMpOfPet(hostObject.getRole(), pet);

        PetFightObject fightObject = new PetFightObject(pet, hostObject, (short) pos);
        RespCombatAddFriend respCombatAddFriend = new RespCombatAddFriend();
        RespCombatAddOpponent respCombatAddOpponent = new RespCombatAddOpponent();
        respCombatAddFriend.setList(new ArrayList<>());
        respCombatAddOpponent.setList(respCombatAddFriend.getList());

        hostObject.setFightPetId(pet.getId());
        fight.addFightObject(fightObject);
        CombatAddObject combatAddObject = new CombatAddObject();
        combatAddObject.setId(pet.getId());
        combatAddObject.setPosition((short) pos);
        combatAddObject.setList(fightObject.asFieldValues());
        if (supply) {
            combatAddObject.setHostId(0);
        } else {
            combatAddObject.setHostId(hostId);
        }
        combatAddObject.setIcon(pet.getIcon());
        respCombatAddFriend.getList().add(combatAddObject);
        return new Pair<>(respCombatAddFriend, respCombatAddOpponent);
    }

    /**
     * 战斗结算
     */
    private void sendReward(Fight fight, Role role, Pet pet) {
        try {

            FightRewardHandler handler = FightRewardHandler.queryHandler(fight.getType());

            if (fight.isWinner(role.getRoleId())) {
                /** 战斗发奖 */
                if (handler != null) {
                    handler.sendReward(fight, role, pet);
                }
                /** 掉落 */
                fightDrop(fight, role);
            } else {
                /** 失败结算 */
                if (handler != null) {
                    handler.fightFailed(fight, role);
                }
            }
        } catch (Exception e) {
           // LoggerUtils.error(e.getMessage(), e);
//            logger.error("退出战斗战斗结算时报错了,战场ID=[{}],角色名=[{}],错误信息[{}]", fight.getId(), role.getName(),
//                    Lang.getStackTrace(e));
        }
    }

    /**
     * 2022-03-17修改 各大boss 奖励为 公共方法
     * 战斗结算 //掉落经验，金钱，道行，等 基础奖励信息。
     */
    public void sendBossBasicsReward(Role role, FightEndEvent fightEndEvent){
        NutMap reward = fightEndEvent.getReward();
        /**道行武学奖励*/
        //经验
        int exp = role.getLevel() * reward.getInt("rewardExp", 0);
        int daohang = fightEndEvent.getReward().getInt("rewardDaohang", 0) * role.getLevel();
        int petWuxue = fightEndEvent.getReward().getInt("petRewardWuxue", 0) * role.getLevel();

        RoleService roleService = SpringUtils.getRoleService();
        roleService.addTao(role, daohang);

        int currPetId = role.getTempCache("fight_current_pet_id", 0);
        Pet pet = SpringUtils.getPetService().getPetById(currPetId, role);
        if (pet != null) {
            roleService.addPetMatiral(role, pet, petWuxue);
        }

        NutMap nutMap = role.getPropsStatus();
        int point = nutMap.getInt("role");
        if (nutMap.getInt("roleStatus") == 1 && point >= 4) {
            nutMap.setv("role", point - 4);
            role.save();
            roleService.addExp(role, exp * 2, role.getLevel(), currPetId);
        } else {
            roleService.addExp(role, exp, role.getLevel(), currPetId);
        }
        // roleService.addExp(role,30000000,role.getLevel(),currPetId);
//        int index = ThreadLocalRandom.current().nextInt(10);
//        if(index<6){
//            // 奖励装备 掉落未鉴定
//            short roleLevel = role.getLevel();
//            String temp = roleLevel + "";
//            if (temp.length() == 3) {
//                roleLevel = Short.parseShort(temp.substring(0, 2) + 0);
//            } else {
//                roleLevel = Short.parseShort(temp.substring(0, 1) + 0);
//            }
//            BagService bagService = SpringUtils.getBean(BagService.class);
//            EquipService equipService = SpringUtils.getBean(EquipService.class);
//
//            short newPos = bagService.getPos(role, false);
//            if (newPos > 0) {
//                equipService.getNotIdentifyEquip(roleLevel, role, newPos);
//            } else {
//                MessagePusher.pushMessage(role, new RespNotifyMiscEx("背包已满，请整理背包"));
//                return;
//            }
//        }
    }

    public void sendBossBasicsRewardNotXing(Role role, FightEndEvent fightEndEvent){
        NutMap reward = fightEndEvent.getReward();
        /**道行武学奖励*/
        //经验
        int exp = role.getLevel() * reward.getInt("rewardExp", 0);
        int daohang = fightEndEvent.getReward().getInt("rewardDaohang", 0) * role.getLevel();
        int petWuxue = fightEndEvent.getReward().getInt("petRewardWuxue", 0) * role.getLevel();

        RoleService roleService = SpringUtils.getRoleService();
        roleService.addTao(role, daohang);

        int currPetId = role.getTempCache("fight_current_pet_id", 0);
        Pet pet = SpringUtils.getPetService().getPetById(currPetId, role);
        if (pet != null) {
            roleService.addPetMatiral(role, pet, petWuxue);
        }

        NutMap nutMap = role.getPropsStatus();
        int point = nutMap.getInt("role");
        if (nutMap.getInt("roleStatus") == 1 && point >= 4) {
            nutMap.setv("role", point - 4);
            role.save();
            roleService.addExp(role, exp * 2, role.getLevel(), currPetId);
        } else {
            roleService.addExp(role, exp, role.getLevel(), currPetId);
        }
    }
    /**
     * 2022-05-23修改 各大boss 奖励为 公共方法
     * 战斗结算 //掉落物品
     * //胜利之后
     */
    public void sendBossExtReward( Role role,FightEndEvent fightEndEvent) {
        try {
            String monsterName = getMonsterNameByType(fightEndEvent.getFightType());
            /** 掉落 */
            List<FightDropSet> fightDropSets = DropDataPool.fightDropBossMap.get(monsterName);

            forDropSet(role,fightDropSets,monsterName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("sendBossExtReward挑战boss结算出错：{}",e);
        }
    }

    public void sendBossExtReward( Role role,int type) {
        try {
            String monsterName = getMonsterNameByType(type);
            /** 掉落 */
            List<FightDropSet> fightDropSets = DropDataPool.fightDropBossMap.get(monsterName);

            forDropSet(role,fightDropSets,monsterName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("sendBossExtReward挑战boss结算出错：{}",e);
        }
    }


    /**
     * 2022-03-17修改 各大boss 奖励为 公共方法
     * 战斗结算 //掉落物品
     */
    public void sendBossReward( Role role,Fight fight,Pet pet) {
        try {
            FightRewardHandler handler = FightRewardHandler.queryHandler(fight.getType());
            if (fight.isWinner(role.getRoleId())) {
                /** 战斗发奖 */
                if (handler != null) {
                    handler.sendReward(fight, role, pet);
                }
                /** 掉落 */
                //fightDrop(fight, role);
            } else {
                /** 失败结算 */
                if (handler != null) {
                    handler.fightFailed(fight, role);
                }
            }
        } catch (Exception e) {
            log.error("退出战斗战斗结算时报错了,战场ID=[{}],角色名=[{}],错误信息[{}]", fight.getId(), role.getName(), e);
        }
    }

    public void forDropSet(Role role,List<FightDropSet> fightDropSets,String dropName){
        if (fightDropSets == null || fightDropSets.size() ==0) {
            //MessagePusher.pushMessage(role, new RespMsg("物品未配置，请联系GM配置。"));
            return;
        }
        for (FightDropSet fightDropSet : fightDropSets) {
            String group = fightDropSet.getDropGroup();
            //新增另外一种随机类型。  有保底类型。 必得  并且 只能 得到一个。
            if(fightDropSet.getIsbaodi() == 1){
                int total = 0;
                for (String s : group.split(",")) {
                    List<DropSet> dropSetList = dropService.getDropSetList(Integer.parseInt(s));
                    for (DropSet dropSet : dropSetList) {
                        int odds = dropSet.getOdds();
                        total += odds;
                    }
                }
                int result = ThreadLocalRandom.current().nextInt(total) + 1;
                int temp = 0;
                for (String s : group.split(",")) {
                    List<DropSet> dropSetList = dropService.getDropSetList(Integer.parseInt(s));
                    for (DropSet dropSet : dropSetList) {
                        temp += dropSet.getOdds();
                        if (result <= temp) {
                            newDropService.addRewardTask(role,dropSet.getExtraParam(),dropSet.getNumor());
                            return;
                        }
                    }
                }
            }else{

                for (String s : group.split(",")) {
                    ThreadLocalUtil.addLocalTask(role, () -> {
                        role.pushTempCache("drop_monster_name", dropName);
                        SpringUtils.getDropService().drop(role,Integer.parseInt(s));
                        role.popTempCache("drop_monster_name");
                    });
                }
            }
        }
    }
    private void fullHpAndMpOfRole(Role role) {
        int maxLife = role.getMaxLife();
        int maxMana = role.getMaxMana();
        if(role.isAi(role)){
            role.setSaveLife(200000000);
            role.setSaveMana(200000000);
        }
        if (role.getSaveLife() >= (maxLife - role.getCurrLife())) {
            RespUpdate respUpdate = new RespUpdate();
            ArrayList<FiedValue> list = new ArrayList<>();
            role.setCurrLife(maxLife);
            role.setSaveLife(role.getSaveLife() - (maxLife - role.getCurrLife()));
            // 储备血量
            list.add(new FiedValue((short) 121, (byte) 3, role.getSaveLife()));
            // 当前血量
            list.add(new FiedValue((short) 6, (byte) 3, role.getCurrLife()));
            respUpdate.setRoleId(role.getRoleId());
            respUpdate.setList(list);
            MessagePusher.pushMessage(role, respUpdate);
        }

        // 储备法力 和法力
        if (role.getSaveMana() >= (maxMana - role.getCurrMana())) {
            RespUpdate respUpdate = new RespUpdate();
            ArrayList<FiedValue> list = new ArrayList<>();
            role.setSaveMana(role.getSaveMana() - (maxMana - role.getCurrMana()));
            role.setCurrMana(maxMana);
            // 储备法力
            list.add(new FiedValue((short) 122, (byte) 3, role.getSaveMana()));
            // 当前法力
            list.add(new FiedValue((short) 11, (byte) 3, role.getCurrMana()));

            respUpdate.setRoleId(role.getRoleId());
            respUpdate.setList(list);
            MessagePusher.pushMessage(role, respUpdate);
        }
    }

    /**
     * 有储备进战斗置满血满蓝 参战宠物置满忠诚
     */
    public void fullLifeRoleAndPet(Role role) {
        // 储备血量 和血量
        fullHpAndMpOfRole(role);
        if (role.getPetBox().getFightPetId() >= 1) {
            Pet pet = petService.getPetById(role.getPetBox().getFightPetId(), role);
            fullHpAndMpOfPet(role, pet);
        }

        role.save();
    }

    public void fullHpAndMpOfPet(Role role, Pet pet) {
        if (pet == null) {
            return;
        }
        int petMaxLife = countService.countPetMaxLife(pet);
        if (role.getSaveLife() >= (petMaxLife - pet.getCurrLife())) {
            RespUpdate respUpdate = new RespUpdate();

            role.setSaveLife(role.getSaveLife() - (petMaxLife - pet.getCurrLife()));
            pet.setCurrLife(petMaxLife);
            // 储备血量
            respUpdate.setRoleId(role.getRoleId());
            respUpdate.setList(Collections.singletonList(new FiedValue((short) 121, (byte) 3, role.getSaveLife())));
            MessagePusher.pushMessage(role, respUpdate);
            // 当前血量
            respUpdate.setList(Collections.singletonList(new FiedValue((short) 6, (byte) 3, pet.getCurrLife())));
            respUpdate.setRoleId(pet.getId());
            MessagePusher.pushMessage(role, respUpdate);
        }

        // 储备法力 和法力
        int petMaxMana = countService.countPetMaxMana(pet);
        if (role.getSaveMana() >= (petMaxMana - pet.getCurrMana())) {
            RespUpdate respUpdate = new RespUpdate();
            role.setSaveMana(role.getSaveMana() - (petMaxMana - pet.getCurrMana()));
            pet.setCurrMana(petMaxMana);
            // 储备法力
            respUpdate.setList(Collections.singletonList(new FiedValue((short) 122, (byte) 3, role.getSaveMana())));
            respUpdate.setRoleId(role.getRoleId());
            MessagePusher.pushMessage(role, respUpdate);
            // 当前法力
            respUpdate.setList(Collections.singletonList(new FiedValue((short) 11, (byte) 3, pet.getCurrMana())));
            respUpdate.setRoleId(pet.getId());
            MessagePusher.pushMessage(role, respUpdate);
        }
        if (role.getSaveLoyalty() >= (100 - pet.getLoyalty())) {
            role.setSaveLoyalty(role.getSaveLoyalty() - (100 - pet.getLoyalty()));
            pet.setLoyalty(100);
            RespUpdate respUpdate = new RespUpdate();
            respUpdate.setList(Collections.singletonList(new FiedValue((short) 178, (byte) 3, role.getSaveLoyalty())));
            respUpdate.setRoleId(role.getRoleId());
            MessagePusher.pushMessage(role, respUpdate);
            // 需要取宠物忠诚度
            respUpdate.setList(Collections.singletonList(new FiedValue((short) 66, (byte) 3, pet.getLoyalty())));
            respUpdate.setRoleId(pet.getId());
            MessagePusher.pushMessage(role, respUpdate);
        }
    }

    /**
     * 战斗开始时的检测操作
     */
    public void checkAtFightStart(Role role) {
        /** 开始战斗时，保证血量大于0 */
        if (role.getCurrLife() <= 0) {
            role.setCurrLife(1);
        }
    }

    /**
     * 是否能进入战斗
     */
    public boolean canFight(Role role, List<Member> list) {
        return !role.getTalk().isInTalk() && !isInFight(role, list);
    }

    /**
     * 野外战斗
     *
     * @param team
     * @param role
     */
    public void enterFieldFight(Team team, Role role) {
        if (canFight(role, team.getList()) == false) {
            return;
        }
        if (teamService.isInTeamAndNotLeader(role)) {
//            logger.info("{}({})不是队长触发战斗", role.getUid(), role.getName());
            return;
        }

        Pos position = role.getPos();
        int mapId = position.getMapId();
        MonsterService monsterService = SpringUtils.getBean(MonsterService.class);
        List<PetSet> monsters = monsterService.getMapMonster(mapId);
        if (CollectionUtils.isEmpty(monsters)) {
            return;
        }
        Fight battleground = FightFactory.getFightFactory(Const.fightType_monster).create(mapId, team, role);

        battleground.start();
    }

    /**
     * 加载队伍信息
     */
    public List<Member> loadTeamBattleInfo(Team team, List<FightMember> fightMemberA, Fight battleground) {
        List<FightObject> memberListA = battleground.getListA();
        battleground.setListA(memberListA);
        FightExecutorService.FIGHTS.put(battleground.getId(), battleground);

        List<Member> list = team.getList();

        int index = 0, petIndex = 5, customIndex = 0;
        for (Member member : list) {
            if (!member.isInTeam()) {
                continue;
            }
            Role tmpRole = SpringUtils.getRoleService().getOnlinePlayer(member.getUid());
            if (tmpRole == null) {
                continue;
            }
            FightExecutorService.FIGHT_ROOMS.put(member.getRoleId(), battleground.getId());
            fullLifeRoleAndPet(tmpRole);// 有储备情况下进战斗自动满血满蓝
            checkAtFightStart(tmpRole);

            FightObject fightObject = new PlayerFightObject(tmpRole, index, customIndex, true);
            ((PlayerFightObject) fightObject).setUseMonthTao(battleground.isUseMonth());
            memberListA.add(fightObject);

            FightMember fightMember = fightObject.asFightMember(battleground.getCustomIconListA());
            fightMemberA.add(fightMember);

            index++;
            customIndex++;

            Pet pet = SpringUtils.getPetService().getPetById(tmpRole.getPetBox().getFightPetId(), tmpRole);
            if (pet != null && pet.canJoinFight()) {
                customIndex++;
                PetFightObject petFightObj = new PetFightObject(pet, fightObject,
                        PositionUtils.positions.get(petIndex));
                memberListA.add(petFightObj);
                FightMember petFightMember = petFightObj.asFightMember();
                fightMemberA.add(petFightMember);
                FightExecutorService.PETID_ROLEID.put(pet.getId(), member.getRoleId());
                FightExecutorService.FIGHT_ROOMS.put(pet.getId(), battleground.getId());
            } else if (pet != null) {
                MessagePusher.pushMessage(tmpRole,new RespNotifyMiscEx("宠物#R忠诚过低#n或者#R寿命过低#n，请及时补充忠诚或者寿命"));
//                MessagePusher.notify2Player(tmpRole, I18nId.PMT_903);
            }
            petIndex++;
        }

        // 加载守护
        if (isGuardJoinFight(battleground.getType()) && index < 5) {
            Role leader = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            for (Member member : team.getShouhus()) {
                if (leader == null) {
                    continue;
                }
                Guard guard = guardService.getGuard(member.getRoleId(), leader);
                if (guard == null || guard.getIsFight() != 1) {
                    continue;
                }
                GuardSet guardSet = guardService.getGuardSet(guard.getName());
                FightObject fightObject = new GuardFightObject(guard, guardSet, PositionUtils.positions.get(index),
                        true);
                memberListA.add(fightObject);
                FightMember fightMember = fightObject.asFightMember();
                fightMemberA.add(fightMember);

                fightObject.setPos(fightMember.getPosition());
                index++;
                if (index >= 5) {
                    break;
                }
            }
        }
        return list;
    }

    /**
     * 判断守护是否加入战斗
     */
    public boolean isGuardJoinFight(int fightType) {
        return fightType != Const.fightType_xinjun && fightType != Const.fightType_pirate
                && fightType != Const.fightType_zhangmen && fightType != Const.fightType_zhengdaodian
                && fightType != Const.fightType_yingxionghui && fightType != Const.fightType_mapGuardian
                && fightType != Const.fightType_elves;
    }

    /**
     * PK战斗
     *
     * @param listA
     * @param listB
     * @param role
     */
    public void enterTeamPK(List<Member> listA, List<Member> listB, Role role) {
        if (canFight(role, listA) == false) {
            return;
        }
        if (canFight(role, listB) == false) {
            return;
        }
        if (teamService.isInTeamAndNotLeader(role)) {
//            logger.info("{}({})不是队长触发战斗", role.getUid(), role.getName());
            return;
        }

        int mapId = role.getPos().getMapId();
        Fight battleground = FightFactory.getFightFactory(Const.fightType_PK).create(mapId, Const.fightType_PK, listA, listB);
        battleground.start();
    }

    /**
     * 根据ID取战场
     */
    public Fight getFightByRoleId(int roleId) {
        Integer fightId = FightExecutorService.FIGHT_ROOMS.get(roleId);
        if (fightId == null) {
            return null;
        }
        return getFight(fightId);
    }

    /**
     * 战斗ID取战斗
     */
    public Fight getFight(int fightId) {
        return FightExecutorService.FIGHTS.get(fightId);
    }

    /**
     * 宠物取主人ID
     */
    public int getHostId(int petId) {
        Integer integer = FightExecutorService.PETID_ROLEID.get(petId);
        return integer == null ? 0 : integer;
    }

    /**
     * 只能调用宠物或者人
     *
     * @param attacker
     * @return
     */
    public SkillAutoPicker getAutoObject(FightObject attacker, Fight fight) {
        SkillAutoPicker useResult = new SkillAutoPicker();
        int skillId = 0;
        try {
            if (attacker.getMultiIndex() == 1) {
                // 组合技能
                pickUpSkillRound(fight, attacker, useResult);
                skillId = useResult.getSkillId();
            } else {
                // 单体技能
                skillId = attacker.getAutoSkillId();
            }
            if (skillId == 0) {
                // 防御
                useResult.setDef(true).setSkillId(skillId).setTargetId(attacker.getId());
                return useResult;
            }
            if (skillId == 2) {
                // 刀光剑影
                FightObject randTarget = getPhysicTarget(attacker, fight);
                if (randTarget != null) {
                    return useResult.setSkillId(skillId).setTargetId(randTarget.getId());
                }
                return useResult;
            }

            RoleSkill roleSkill = attacker.getSkillBy(skillId);
            // 法宝特殊主动技能
            if (SpringUtils.getArtifactService().isArtifactSkill(skillId)) {
                useResult = ArtifactSkillProcessor.getSkillProcessor(skillId).autoFightTarget(fight, attacker, skillId);
                return useResult;
            }

            int autoTargetId = attacker.getAutoTarget();
            FightObject autoTarget = fight.queryFightObject(autoTargetId);

            if (roleSkill == null) {
                if (autoTarget != null && !autoTarget.isFallDown()) {
                    if (autoTarget.isASide() != attacker.isASide()) {
                        return useResult.setSkillId(skillId).setTargetId(autoTarget.getId());
                    }
                }
                FightObject randTarget = getPhysicTarget(attacker, fight);
                if (randTarget != null) {
                    return useResult.setSkillId(skillId).setTargetId(randTarget.getId());
                }
                return useResult;
            }

            int skillTargetSum = SpringUtils.getSkillService().getSkillTargetNum(roleSkill);

            if (autoTarget == null || autoTarget.isFallDown()) {
                if (roleSkill.isAssistSkill()) {
                    attacker.setTargetId(0);
                    attacker.setSkillId(roleSkill.getSkillId());
                    int tempRoleId = getTargetListNew(attacker, skillTargetSum, fight).get(0);
                    return useResult.setSkillId(skillId).setTargetId(tempRoleId);
                } else {
                    attacker.setTargetId(0);
                    attacker.setSkillId(roleSkill.getSkillId());
                    List<Integer> arrayList = getTargetListNew(attacker, skillTargetSum, fight);
                    if (!CollectionUtils.isEmpty(arrayList)) {
                        int tempRoleId = arrayList.get(0);
                        return useResult.setSkillId(skillId).setTargetId(tempRoleId);
                    }
                    attacker.setTargetId(0);
                    attacker.setSkillId(roleSkill.getSkillId());
                    int tempRoleId = getTargetBySkill(attacker, fight).getId();
                    return useResult.setSkillId(skillId).setTargetId(tempRoleId);
                }
            } else {
                if (roleSkill.isAssistSkill() || SpringUtils.getArtifactService().isArtifactSkill(roleSkill.getSkillId())) {
                    // 对己方释放
                    if (autoTarget.isASide() == attacker.isASide()) {
                        return useResult.setSkillId(skillId).setTargetId(autoTarget.getId());
                    }
                    attacker.setTargetId(0);
                    attacker.setSkillId(roleSkill.getSkillId());
                    int tempRoleId = getTargetListNew(attacker, skillTargetSum, fight).get(0);
                    return useResult.setSkillId(skillId).setTargetId(tempRoleId);
                } else {
                    // 对敌方释放
                    if (autoTarget.isASide() != attacker.isASide()) {
                        return useResult.setSkillId(skillId).setTargetId(autoTarget.getId());
                    }
                    attacker.setTargetId(0);
                    attacker.setSkillId(roleSkill.getSkillId());
                    List<Integer> targetListNew = getTargetListNew(attacker, skillTargetSum, fight);
                    if (CollectionUtils.isEmpty(targetListNew)) {
                        return useResult;
                    }
                    int tempRoleId = targetListNew.get(0);
                    return useResult.setSkillId(skillId).setTargetId(tempRoleId);
                }
            }
        } catch (Exception e) {
           // LoggerUtils.error(e.getMessage(), e);
        } finally {
            if (!useResult.isDef()) {
                if (useResult.getSkillId() <= 0) {
//                    logger.error("fight[{}], type[{}],{} 技能{} 取不到目标 {}", fight.getId(), fight.getType(),
//                            attacker.getClass().getSimpleName(), skillId, useResult.getTargetId());
                }
            }
        }
        return useResult;
    }

    /**
     * 根据技能类型取目标
     */
    private FightObject getTargetBySkill(FightObject attacker, Fight fight) {
        RoleSkill skill = attacker.getSkillBy(attacker.getSkillId());
        if (attacker.getType() == 2) {
            return fight.getAttackTarget(attacker);
        } else if (attacker.getType() == 1) {
            return attacker;// 防御目标设置为自己
        } else if (attacker.getType() == 3) {
            return getAutoTarget(skill, attacker, fight);
        }
        return null;
    }

    /**
     * 返回组合技能
     */
    private void pickUpSkillRound(Fight fight, FightObject attacker, SkillAutoPicker autoConfig) {
        List<SkillGroup> list = attacker.getSkillGroups();
        if (list == null || list.size() <= 0) {
            // 没有技能ID 默认物攻
            autoConfig.setSkillId(2);
            return;
        }
        int total = 0;
        for (SkillGroup skillGroup : list) {
            total += skillGroup.getRound();
        }
        int round = fight.getRound() % total;
        int skillId = 0;
        int type = 0;
        int lastRound = 0;
        int index = 0;
        int nextSkillId = 0;
        int nextType = 0;
        SkillGroup first = list.get(0);
        if (first != null) {
            if (list.size() == 1) {
                skillId = first.getSkillId();
                type = first.getType();
                lastRound = first.getRound() - round + 1;
                nextSkillId = list.get(0).getSkillId();
                nextType = list.get(0).getType();

                autoConfig.setLastRound(lastRound);
                autoConfig.setType(type);
                autoConfig.setSkillId(skillId);
                autoConfig.setNextType(nextType);
                autoConfig.setNextSkillId(nextSkillId);
                return;
            }
            if (round == 0) {
                skillId = list.get(list.size() - 1).getSkillId();
                type = list.get(list.size() - 1).getType();
                lastRound = 1;
                nextSkillId = list.get(0).getSkillId();
                nextType = list.get(0).getType();
                autoConfig.setLastRound(lastRound);
                autoConfig.setType(type);
                autoConfig.setSkillId(skillId);
                autoConfig.setNextType(nextType);
                autoConfig.setNextSkillId(nextSkillId);
                return;
            }
            if (round <= first.getRound() && round > 0) {
                skillId = first.getSkillId();
                type = first.getType();
                lastRound = first.getRound() - round + 1;
                index = 0;
            } else {
                SkillGroup second = list.get(1);
                if (round <= first.getRound() + second.getRound() && round > first.getRound()) {
                    skillId = second.getSkillId();
                    type = second.getType();
                    lastRound = second.getRound() + first.getRound() - round + 1;
                    index = 1;
                } else {
                    SkillGroup third = list.get(2);
                    skillId = third.getSkillId();
                    type = third.getType();
                    if (round > 0) {
                        lastRound = third.getRound() - (-second.getRound() - first.getRound() + round) + 1;
                    } else {
                        lastRound = 1;
                    }
                    index = 2;
                }
            }
        }
        if (index == 0) {
            if (list.size() >= 2) {
                nextSkillId = list.get(1).getSkillId();
                nextType = list.get(1).getType();
            } else {
                nextSkillId = skillId;
                nextType = type;
            }
        } else if (index == 1) {
            if (list.size() >= 3) {
                nextSkillId = list.get(2).getSkillId();
                nextType = list.get(2).getType();
            } else {
                nextSkillId = skillId;
                nextType = type;
            }
        } else {
            nextSkillId = list.get(0).getSkillId();
            nextType = list.get(0).getType();
        }
        autoConfig.setLastRound(lastRound);
        autoConfig.setType(type);
        autoConfig.setSkillId(skillId);
        autoConfig.setNextType(nextType);
        autoConfig.setNextSkillId(nextSkillId);
        return;
    }

    /**
     * 自动战斗选目标
     */
    private FightObject getAutoTarget(RoleSkill roleSkill, FightObject fightObject, Fight fight) {
        FightObject autoTarget = fight.queryFightObject(fightObject.getAutoTarget());
        if (fightObject.getAutoFightType() == 1) {
            return fightObject;
        } else if (fightObject.getAutoFightType() == 2) {
            if (autoTarget != null && !autoTarget.isFallDown()) {
                if (autoTarget.isASide() != fightObject.isASide()) {
                    return autoTarget;
                } else {
                    return fight.getAttackTarget(fightObject);
                }
            } else {
                return fight.getAttackTarget(fightObject);
            }
        } else if ((fightObject.getAutoFightType() == 3)) {
            if (autoTarget != null && !autoTarget.isFallDown()) {
                if (roleSkill.isAssistSkill()) {
                    if (fightObject.isASide() != autoTarget.isASide()) {
                        return fight.getAttackSelf(fightObject);
                    } else {
                        return autoTarget;
                    }
                } else {
                    if (fightObject.isASide() == autoTarget.isASide()) {
                        return fight.getAttackTarget(fightObject);
                    } else {
                        return autoTarget;
                    }
                }
            } else {
                if (roleSkill.isAssistSkill()) {
                    return fight.getAttackSelf(fightObject);
                } else {
                    return fight.getAttackTarget(fightObject);
                }
            }
        }
        return null;
    }

    /**
     * 单人自动出手
     */
    public void autoFightOne(Fight fight, FightObject attacker) {
        autoFightOne(fight, attacker, 2500);
    }

    /**
     * 单人自动出手
     */
    public void autoFightOne(Fight fight, FightObject attacker, long delay) {
        fightExecutorService.addFightTask(fight, () -> {
            try {
                if (fight.isOver())
                    return;
                if (attacker.getAutoFight() == 1) {// 如果是自动
                    ReqFightDoAction doAction = fightMessageService.autoFightOne(fight, attacker);
                    if (doAction == null) {// 如果为空 战斗结束了
                        //log.error("fight[{}], type[{}],{}出手动作为空", fight.getId(), fight.getType(), attacker);
                        return;
                    }

                    AutoChuShouTask autoTask = new AutoChuShouTask(doAction, fight);
                    ScheduledFuture<?> timeOut = SchedulerManager.getInstance().schedule(autoTask, delay);
                    fight.addHostTask(doAction.getAttackerId(), timeOut);
                    ////// 宠物自动
                    if (attacker.getFightPetId() > 0) {
                        FightObject petObject = fight.queryFightObject(attacker.getFightPetId());
                        if (petObject != null) {
                            doAction = fightMessageService.autoFightOne(fight, petObject);
                            if (doAction == null) {// 如果为空 战斗结束了
//                                logger.error("fight[{}], type[{}],{}出手动作为空", fight.getId(), fight.getType(), attacker);
                                return;
                            }
                            AutoChuShouTask petAutoTask = new AutoChuShouTask(doAction, fight);
                            ScheduledFuture<?> petTimeOut = SchedulerManager.getInstance().schedule(petAutoTask,
                                    delay + 20);
                            fight.addPetTask(doAction.getAttackerId(), petTimeOut);
                        }
                    }
                }
            } catch (Exception e) {
                //log.error("fight[{}], type[{}],自动战斗出错{}", fight.getId(), fight.getType(), e);

                ReqFightDoAction ReqFightDoAction = new ReqFightDoAction();
                ReqFightDoAction.setAttackerId(attacker.getId());
                ReqFightDoAction.setTargetId(attacker.getId());
                ReqFightDoAction.setSkillId(0);
                ReqFightDoAction.setType(1);
                AutoChuShouTask autoTask = new AutoChuShouTask(ReqFightDoAction, fight);
                ScheduledFuture<?> timeOut = SchedulerManager.getInstance().schedule(autoTask, delay);
                fight.addHostTask(ReqFightDoAction.getAttackerId(), timeOut);

                if (attacker.getFightPetId() > 0) {
                    FightObject petObject = fight.queryFightObject(attacker.getFightPetId());
                    if (petObject != null) {
                        ReqFightDoAction doAction = new ReqFightDoAction();
                        doAction.setAttackerId(petObject.getId());
                        doAction.setTargetId(petObject.getId());
                        doAction.setSkillId(0);
                        doAction.setType(1);

                        AutoChuShouTask petAutoTask = new AutoChuShouTask(doAction, fight);
                        ScheduledFuture<?> petTimeOut = SchedulerManager.getInstance().schedule(petAutoTask,
                                delay + 20);
                        fight.addPetTask(doAction.getAttackerId(), petTimeOut);
                    }
                }
            }
        });
    }

    /**
     * 重置出手状态为false
     *
     * @param fight
     * @param reqFightDoAction
     */
    public void resetDoActionStatus(Fight fight, ReqFightDoAction reqFightDoAction) {
        int hostId = getHostId(reqFightDoAction.getAttackerId());
        /* 主人的对象 */
        FightObject hostObj = fight.queryFightObject(hostId);
        if (hostObj != null) {
            hostObj.setDoAction(false);
        }
    }

    /**
     * 判断目标是否是己方
     *
     * @return
     */
    public boolean isSameTeam(FightObject attacker, FightObject target) {
        return attacker.isASide() == target.isASide();
    }

    /**
     * 判断怪物目标是否可以加血
     */
    private boolean canUseLifeItem(Fight fight) {
        return fight.getType() == Const.fightType_xinjun || fight.getType() == Const.fightType_superboss;
    }

    /**
     * 怪物AI
     */
    private void monsterAI(Fight fight) {
        if (fight.isPkFight()) {
            return;
        }
        Random random = new Random();
        fight.getListA().forEach(attacker -> {
            /** 没有出手的才更新 避免重复更新 */ /** 更新己方守护出手 */
            if (!attacker.isDoAction() && attacker.isGuard()) {
                Guard guard = ((GuardFightObject) attacker).getGuardObject();
                /** 取出守护能释放辅助技能 */
                List<Integer> assistSkills = new ArrayList<>(guard.getAssistSkills());
                /** 取出守护能释放攻击技能 */
                List<Integer> attackSkills = new ArrayList<>(guard.getAttackSkills());
                int value = fight.getRound() % 4;
                if (guard.getType() == 0) {/** 攻击技能取敌方目标 */
                    int index = random.nextInt(attackSkills.size());
                    attacker.setSkillId(attackSkills.get(index));
                    for (FightObject target : fight.getListB()) {
                        if (target.isFallDown()) {
                            continue;
                        }
                        attacker.setTargetId(target.getId());
                        break;
                    }
                } else {
                    if (value == 1) {/** 辅助技能取己方目标 */
                        int index = random.nextInt(assistSkills.size());
                        attacker.setSkillId(assistSkills.get(index));
                        attacker.setTargetId(fight.getListA().get(0).getId());
                    } else {
                        int index = random.nextInt(attackSkills.size());
                        attacker.setSkillId(attackSkills.get(index));
                        for (FightObject target : fight.getListB()) {
                            if (target.isFallDown()) {
                                continue;
                            }
                            attacker.setTargetId(target.getId());
                            break;
                        }
                    }
                }
                attacker.setDoAction(true);
            }
        });

        fight.getListB().forEach(attacker -> {
            /** 没有出手的才更新 避免重复更新 */
            if (!attacker.isDoAction()) {
                /** 帮派日常任务猜真假 */
                if (fight.getData() != null && fight.getData().getBoolean("fight_guess_true", false)) {
                    attacker.setType(FightAction.NULL);

                    /** 帮派日常任务顺序打倒对应的怪物 */
                } else if (fight.getData() != null && fight.getData().getBoolean("fight_order_target", false)) {
                    attacker.setType(FightAction.DEFENSE);

                    /** 如果是财神 */
                } else if (fight.getData() != null && fight.getData().getBoolean("fight_npc_boss_refresh", false) && !"功夫龙".equals(attacker.getName())) {
                    attacker.setType(FightAction.NULL);
                    boolean fight_npc_boss_angry = fight.getData().getBoolean("fight_npc_boss_angry", false);
                    if(fight_npc_boss_angry && "财神".equals(attacker.getName())){
                        //财神放大招
                        attacker.setType(FightAction.CAST_MAGIC);
                        int index = random.nextInt(attacker.getSkillIds().size());
                        attacker.setSkillId(attacker.getSkillIds().get(index));
                        fight.getData().remove("fight_npc_boss_angry");
                    }

                    /** 如果是星君 掌门 超级BOSS */
                }  else if (canUseLifeItem(fight)) {
                    if (attacker.getCurrLife() < attacker.getMaxLife() * 0.2) {/** 血量低于20%给自己加血 */
                        attacker.setType(FightAction.APPLY_ITEM);
                    } else {
                        FightObject hostObject = fight.queryFightObject(attacker.getHostId());
                        if (hostObject != null && hostObject.isFallDown()) {/** 主人倒下给主人加血 */
                            attacker.setTargetId(hostObject.getId());
                            attacker.setType(FightAction.APPLY_ITEM);
                        } else {
                            attacker.setType(attacker.getPolar() == 0 || attacker.getSkillIds().size() == 0
                                    ? FightAction.PHYSICAL_ATTACK
                                    : FightAction.CAST_MAGIC);
                            if (attacker.getType() == FightAction.CAST_MAGIC) {
                                if (attacker.isSuperBoss()) {
                                    /**超级boss*/
                                    SuperBossFightObject boss = (SuperBossFightObject) attacker;
                                    boss.setSkillId(boss.getSkillChooser().nextSkill(fight.getRound()));
//                                    logger.error("世界boss选择技能=={}",attacker.getName(),boss.getSkillId());
                                } else {
                                    int index = random.nextInt(attacker.getSkillIds().size());
                                    attacker.setSkillId(attacker.getSkillIds().get(index));
                                }
                            } else {
                                attacker.setSkillId(2);
                            }
                        }
                    }

                    /** 其他的怪物? */
                } else if (fight.getType() != Const.fightType_monster) {
                    boolean canUseMagic = attacker.getSkillIds().size() > 0/* && attacker.getCurrMana() > 0 */;
                    // fightObject. getPolar() == 0 || fightObject.getSkillIds().size() == 0 ?
                    // FightAction.PHYSICAL_ATTACK : FightAction.CAST_MAGIC
                    attacker.setType(canUseMagic ? FightAction.CAST_MAGIC : FightAction.PHYSICAL_ATTACK);
                    if (attacker.getType() == FightAction.CAST_MAGIC) {
                        if (attacker instanceof BossFightObject) {
                            BossFightObject boss = (BossFightObject) attacker;
                            boss.setSkillId(boss.getSkillChooser().nextSkill(fight.getRound()));
                        } else if (attacker.isRoleMirror()) {
                            RoleMirrorFightObject mirror = (RoleMirrorFightObject) attacker;
                            mirror.setSkillId(mirror.getSkillChooser().nextSkill(fight.getRound()));
                        } else {
                            int index = random.nextInt(attacker.getSkillIds().size());
                            attacker.setSkillId(attacker.getSkillIds().get(index));
                        }
                    } else {
                        attacker.setSkillId(2);
                    }
                } else {
                    /** 野怪出手技能根据等级写进了配置 直接随机 */
                    int index = random.nextInt(attacker.getSkillIds().size());
                    attacker.setSkillId(attacker.getSkillIds().get(index));
                    attacker.setType(FightAction.CAST_MAGIC);
                }
                attacker.setDoAction(true);
            }
        });
    }

    /**
     * 更新出手状态
     */
    private void updateDoActionStatus(Fight fight, int attackerId, int targetId, int actionType, int skillId) {
        FightObject attacker = fight.queryFightObject(attackerId);
        if (attacker != null) {
            attacker.setSkillId(skillId);
            attacker.setTargetId(targetId);
            attacker.setType(actionType);
            attacker.setDoAction(true);
        }
    }

    /**
     * 清除战场
     */
    public void clearFight(Fight fight) {
        if (fight == null) {
            return;
        }
        fight.destroy();
    }

    /**
     * 抓宠物
     */
    private void catchPet(FightObject fightObject, Fight fight) {
        if (checkDeStatus(fight, fightObject)) {
            return;
        }
        if (!fightObject.isPlayer()) {
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }
        Role role = fightObject.getRole();
        FightObject target = fight.queryFightObject(fightObject.getTargetId());
        if (target == null) {
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }
        boolean flag = true;
        // 判断该宠物携带等级
        Random random = new Random();
        int success = random.nextInt(6);
        if (SpringUtils.getPetService().isEquippedFull(role)) {
            MessagePusher.pushMessage(role, new RespMsg("当前宠物包裹已满，请整理后再来吧。"));
            success = 5;
        }
        PetObject petObject = PetDataPool.getPetObject(target.getName());
        if (petObject.getLevel_req() <= fightObject.getLevel()) {
            if (success < 3) {
                RespMsg respMsg = new RespMsg();
                respMsg.setMsg("捕捉成功！恭喜你获得#R" + target.getName() + "#n做为你的宠物！");
                target.setCurrLife(0);
                RespSyncMessage respSyncMessage = new RespSyncMessage();
                respSyncMessage.setCode((short) 8165);
                respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respMsg));
                MessagePusher.pushMessage(role, respSyncMessage);

                RespIconCartoon respIconCartoon = new RespIconCartoon();
                respIconCartoon.setType((short) 2);
                respIconCartoon.setName(target.getName());
                respIconCartoon.setParam(target.getIcon() + "");
                respSyncMessage = new RespSyncMessage();
                respSyncMessage.setCode((short) 40964);
                respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respIconCartoon));
                MessagePusher.pushMessage(role, respSyncMessage);

                // 添加宠物
                Pet pet = petService.addWildPet(petObject, role);
                petService.loadPet(role, pet);
            } else {
                RespMsg respMsg = new RespMsg();
                respMsg.setMsg("捕捉失败。");
                RespSyncMessage respSyncMessage = new RespSyncMessage();
                respSyncMessage.setCode((short) 8165);
                respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respMsg));
                MessagePusher.pushMessage(role, respSyncMessage);
                flag = false;
            }
        } else {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("#Y" + target.getName() + "#n携带等级超过人物等级，不可捕捉。");
            RespSyncMessage respSyncMessage = new RespSyncMessage();
            respSyncMessage.setCode((short) 8165);
            respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respMsg));
            MessagePusher.pushMessage(role, respSyncMessage);
        }

        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(fightObject, 1, 0, 0));
        if (flag) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.disappear(target.getId()));
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));
    }

    /**
     * 召唤宠物
     */
    public void selectPet(FightObject fightObject, Fight fight) {
        if (checkDeStatus(fight, fightObject)) {
            return;
        }
        int oldPetId = fightObject.getSkillId();
        int newPetId = fightObject.getTargetId();
        Role role = fightObject.getRole();
        Pet newPet = SpringUtils.getPetService().getPetById(newPetId, role);
        Pair<Message, Message> selectMessage = addPet2Fight(fightObject.getId(), newPet, fight, fightObject.getPos() + 5, true);
        // 设置主人id
        fightObject.setFightPetId(newPet.getId());
        sendQiMiSkills(role, newPetId);
        fightObject.setSkillId(0);
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));
        // 当前宠物从战斗场景消失
        FightObject delPet = fight.queryFightObject(oldPetId);
        if (delPet != null) {
            delPet.setCurrLife(0);
            FightMessageUtil.sendFightPackage(fight, fightMessageService.disappear(delPet.getId()));
            fight.removeFightObject(delPet);
        }
        // 重新获取宠物列表
        RespRefreshPetList respRefreshPetList = new RespRefreshPetList();
        RefreshPet refreshPet = new RefreshPet();
        ArrayList<RefreshPet> refreshPets = new ArrayList<>();
        refreshPets.add(refreshPet);
        refreshPet.setPetId(newPet.getId());
        respRefreshPetList.setPetList(refreshPets);
        MessagePusher.pushMessage(role, respRefreshPetList);
        // 设置召唤宠物
        RespSetFightPetStatus respSetFightPetStatus = new RespSetFightPetStatus();
        respSetFightPetStatus.setRoleId(newPet.getId());
        respSetFightPetStatus.setType((short) 1);
        MessagePusher.pushMessage(role, respSetFightPetStatus);
        // 更新服务端存储数据
        FightExecutorService.PETID_ROLEID.put(newPet.getId(), newPet.getHostId());
        FightExecutorService.FIGHT_ROOMS.put(newPet.getId(), fight.getId());
        // 更新宠物信息面板
        RespPetInfo respPetInfo = new RespPetInfo();
        ArrayList<EquipField> list = new ArrayList<>();
        PetInfo petInfo = new PetInfo();
        respPetInfo.setPetInfos(new ArrayList<>());
        boolean add = respPetInfo.getPetInfos().add(petInfo);
        petInfo.setPosition(newPet.getPosition());
        petInfo.setPetId(newPet.getId());
        list.addAll(newPet.getAllFields());
        byte[] body = AsktaoUtil.getMessageBody(respPetInfo);
        RespSyncMessage respSyncMessage = new RespSyncMessage();
        respSyncMessage.setCode((short) 65507);
        respSyncMessage.setMsg(body);
        MessagePusher.pushMessage(role, respSyncMessage);
        // 调整宠物出站（闪现出来）
        sendPairFightMessage(fight, fightObject, selectMessage);
        FightMessageUtil.sendFightPackage(fight, fightMessageService.fightShouting(fight.queryFightObject(newPet.getId()), "出战"));
        PetBook petBook = getRandomBook(role, newPet.getId());
        if (petBook != null) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.summonPetBookEffect(newPet.getId(), petBook.getFightIcon()));
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));

        // 返回宠物参战-刷新
        RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
        respSetCurrentPet.setPetId(newPet.getId());
        respSetCurrentPet.setStatus((short) 1);
        respSyncMessage = new RespSyncMessage();
        respSyncMessage.setCode((short) 4163);
        respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respSetCurrentPet));
        MessagePusher.pushMessage(role, respSyncMessage);
    }

    /**
     * 逃跑
     */
    private void flee(FightObject fightObject, Fight fight) {
        Role role = fightObject.getRole();
        if (role == null) {
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }
        /**逃跑失败*/
        if (!canFlee(fightObject, fight)) {
            SpringUtils.getTeamService().pushMessage(role, new RespMsg("逃跑失败。"));
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }

        FightRewardHandler handler = FightRewardHandler.queryHandler(fight.getType());
        if (handler != null) {
            handler.flee(fight, role);
        }
        /** 设置战斗结束时间 */
        role.setPrevFightEndTime(System.currentTimeMillis());


        resetAfterLeaveFight(fight, fightObject);

        if (fight.getId() == FightExecutorService.FIGHT_ROOMS.get(fightObject.getId())) {
            FightExecutorService.PETID_ROLEID.remove(fightObject.getFightPetId());
            FightExecutorService.FIGHT_ROOMS.remove(fightObject.getId());
        }
        // add tao 如果队伍中只有一人，逃跑时不解散队伍
        int teamCount = teamService.getTeamCount(role);
        if (teamCount > 1) {
           teamService.leave(role, false);
        }

//        logger.error("fightId[{}], {}战斗逃跑", fight.getId(),
//                fightObject.getRole() != null ? fightObject.getRole().getName() : "");

     broadcastService.sendTitleInfo(role);

        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));

        FightMessageUtil.sendFightPackage(fight, fightMessageService.disappear(fightObject.getId()));
        FightObject petObject = fight.queryFightObject(fightObject.getFightPetId());
        if (petObject != null) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.disappear(petObject.getId()));
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));

        // 当前用户逃跑
        RespSetFightPetStatus respSetFightPetStatus = new RespSetFightPetStatus();
        respSetFightPetStatus.setRoleId(fightObject.getId());
        respSetFightPetStatus.setType((short) 0);
        MessagePusher.pushMessage(role, respSetFightPetStatus);
        RespEndCombat respEndCombat = new RespEndCombat();
        MessagePusher.pushMessage(role, respEndCombat);

        /** 产生一个战斗逃跑事件 */
        role.setLastDead(fightObject.getCurrLife()<=0?0:1);
        EventDispatcher.getInstance().fireEvent(new FightEndEvent(fight, EventType.FIGHT_END, role, fight.getId(),
                FightEndEvent.RUNAWAY, fight.getType(), fight.getBossReward(), fight.getTaskId(), fight.getNpcId(), 0));

        // 取出宠物 发送状态?
        Set<Integer> petSet = role.getPetBox().equippedPets(role);
        for (Integer petid : petSet) {
            if (role.getPetBox().getFightPetId() == petid) {
                RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
                respSetCurrentPet.setPetId(petid);
                respSetCurrentPet.setStatus((short) 1);
                MessagePusher.pushMessage(role, respSetCurrentPet);
            } else if (role.getPetBox().getSupplyPetId() == petid) {
                RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
                respSetCurrentPet.setPetId(petid);
                respSetCurrentPet.setStatus((short) 2);
                MessagePusher.pushMessage(role, respSetCurrentPet);
            } else {
                respSetFightPetStatus = new RespSetFightPetStatus();
                respSetFightPetStatus.setRoleId(petid);
                MessagePusher.pushMessage(role, respSetFightPetStatus);
            }
        }

        fight.removeFightObject(fightObject);

        if (petObject != null) {
            respSetFightPetStatus = new RespSetFightPetStatus();
            respSetFightPetStatus.setRoleId(petObject.getId());
            respSetFightPetStatus.setType((short) 0);
            MessagePusher.pushMessage(role, respSetFightPetStatus);

            fight.removeFightObject(petObject);
        }

        role.save();
    }

    /**
     * 是否可以逃跑
     */
    private boolean canFlee(FightObject fightObject, Fight fight) {
        int substractOdds = 0;
        if (fight.getType() == Const.fightType_forcePK) {
            /**处于障碍状态，不能逃跑*/
            if (fightObject.inDeBuffStatus()) {
                return false;
            }

            if (fightObject.isASide()) {
                return false;
            }
                substractOdds = 20;

        }

        int rand = ThreadLocalRandom.current().nextInt(100);
        int odds = 100 - substractOdds;
        return rand < odds;
    }

    private void resetAfterLeaveFight(Fight fight, FightObject fightObject) {
        Role role = fightObject.getRole();
        int lastLife = fightObject.getCurrLife();
        int lastMana = fightObject.getCurrMana();
        int maxLife = role.getMaxLife();
        int maxMana = role.getMaxMana();

        int needLife = maxLife - lastLife;
        int saveLife = role.getSaveLife();
        int needMana = maxMana - lastMana;
        int saveMna = role.getSaveMana();

        if (saveLife >= 1) {// 储备血量大于0
            if (saveLife >= needLife) {
                lastLife = maxLife;// 置当前血量为满
                saveLife -= needLife;
            } else {
                lastLife += saveLife;// 储备不够 置当前血量为储备剩余的血量
                saveLife = 0;
            }
        } else {// 没有储备血量
            if (lastLife <= 0) {
                lastLife = 1;// 如果出战斗血量为0 置1
            }
            saveLife = 0;
        }

        if (saveMna >= 1) {// 储备血量大于0
            if (saveMna >= needMana) {
                lastMana = maxMana;// 置当前血量为满
                saveMna -= needMana;
            } else {
                lastMana += saveMna;// 储备不够 置当前血量为储备剩余的血量
                saveMna = 0;
            }
        } else {// 没有储备血量
            if (lastMana <= 0) {
                lastMana = 1;// 如果出战斗血量为0 置1
            }
            saveMna = 0;
        }
        role.setCurrLife(lastLife);
        role.setCurrMana(lastMana);
        Map<String, Object> autoSet = role.getExtendBox().getAutoFightSet();
        autoSet.put("type", fightObject.getAutoFightType());
        autoSet.put("skillId", fightObject.getAutoSkillId());
        autoSet.put("action", (int)fightObject.getAction());
        autoSet.put("multi", (int)fightObject.getMultiIndex());
        autoSet.put("list", fightObject.getSkillGroups());
        role.setAutoFight(fightObject.getAutoFight());

        int petId = fightObject.getFightPetId();
        if (petId >= 1) {// 参战宠物不为空
            Pet pet = SpringUtils.getPetService().getPetById(petId, role);
            FightObject petObject = fight.queryFightObject(petId);
            if (petObject != null && pet != null) {

                lastLife = petObject.getCurrLife();
                lastMana = petObject.getCurrMana();
                maxLife = countService.countPetMaxLife(pet);
                maxMana = countService.countPetMaxMana(pet);
                needLife = maxLife - lastLife;
                needMana = maxMana - lastMana;

                if (saveLife >= 1) {// 储备血量大于0
                    if (saveLife >= needLife) {
                        lastLife = maxLife;// 置当前血量为满
                        saveLife -= needLife;
                    } else {
                        lastLife += saveLife;// 储备不够 置当前血量为储备剩余的血量
                        saveLife = 0;
                    }
                } else {// 没有储备血量
                    if (lastLife <= 0) {
                        lastLife = 1;// 如果出战斗血量为0 置1
                    }
                    saveLife = 0;
                }

                if (saveMna >= 1) {// 储备血量大于0
                    if (saveMna >= needMana) {
                        lastMana = maxMana;// 置当前血量为满
                        saveMna -= needMana;
                    } else {
                        lastMana += saveMna;// 储备不够 置当前血量为储备剩余的血量
                        saveMna = 0;
                    }
                } else {// 没有储备血量
                    if (lastMana <= 0) {
                        lastMana = 1;// 如果出战斗血量为0 置1
                    }
                    saveMna = 0;
                }
                int petShouming = pet.getLongevity() - 1;// 一场战斗减少5点寿命
                if (petShouming <= 0) {
                    petShouming = 0;
                }
                pet.setCurrMana(lastMana);
                pet.setCurrLife(lastLife);
                pet.setLoyalty(pet.getLoyalty() - 1);
                pet.setLongevity(petShouming);
                autoSet = NutMap.NEW();
                autoSet.put("type", petObject.getAutoFightType());
                autoSet.put("skillId", petObject.getAutoSkillId());
                autoSet.put("action", (int)petObject.getAction());
                autoSet.put("multi", (int)petObject.getMultiIndex());
                autoSet.put("list", petObject.getSkillGroups());
                pet.setAutoFightSet(autoSet);
                petService.refreshPetInfo(role, pet);

                if (role.getSaveLoyalty() >= (100 - pet.getLoyalty())) {
                    role.setSaveLoyalty(role.getSaveLoyalty() - (100 - pet.getLoyalty()));
                    pet.setLoyalty(100);
                    RespUpdate respUpdate = new RespUpdate();
                    respUpdate.setList(
                            Collections.singletonList(new FiedValue((short) 178, (byte) 3, role.getSaveLoyalty())));
                    respUpdate.setRoleId(role.getRoleId());
                    MessagePusher.pushMessage(role, respUpdate);
                    // 需要取宠物忠诚度
                    respUpdate
                            .setList(Collections.singletonList(new FiedValue((short) 66, (byte) 3, pet.getLoyalty())));
                    respUpdate.setRoleId(pet.getId());
                    MessagePusher.pushMessage(role, respUpdate);
                }
            }
        }

        role.setSaveMana(saveMna);
        role.setSaveLife(saveLife);

        // 刷新角色信息
        roleService.sendExtraAttribute(role);
        role.save();

    }

    /**
     * 召唤宠物
     */
    private void callbackPet(FightObject fightObject, Fight fight) {
        if (checkDeStatus(fight, fightObject)) {
            return;
        }
        boolean flag = false;
        FightObject target = fight.queryFightObject(fightObject.getTargetId());
        Role role = fightObject.getRole();
        fightObject.setFightPetId(0);
        role.save();
        if (target != null && !target.isFallDown()) {
            target.setCurrLife(0);
        } else {
            // 宠物已经挂了,没必要播放后面的动画
            flag = true;
        }

        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));
        if (target != null) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.disappear(target.getId()));
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));

        if (!flag) {
            RespSetFightPetStatus respSetFightPetStatus = new RespSetFightPetStatus();
            respSetFightPetStatus.setRoleId(fightObject.getTargetId());
            respSetFightPetStatus.setType((short) 0);
            MessagePusher.pushMessage(role, respSetFightPetStatus);

            RespNotifyMiscEx respNotifyMiscEx = new RespNotifyMiscEx();
            respNotifyMiscEx.setTime(new Long(new Date().getTime() / 1000).intValue());
            respNotifyMiscEx.setMsg("你成功将#R" + target.getName() + "#n召回。");
            RespSyncMessage respSyncMessage = new RespSyncMessage();
            respSyncMessage.setCode((short) 20481);
            respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respNotifyMiscEx));
            MessagePusher.pushMessage(role, respSyncMessage);

            RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
            respSetCurrentPet.setPetId(target.getId());
            respSetCurrentPet.setStatus((short) 0);
            RespSyncMessage syncMessage = new RespSyncMessage();
            syncMessage.setCode((short) 4163);
            syncMessage.setMsg(AsktaoUtil.getMessageBody(respSetCurrentPet));
            MessagePusher.pushMessage(role, syncMessage);

            fight.removeFightObject(target);
        }
    }

    /**
     * 随机取战斗触发天书
     */
    public PetBook getPetFightBook(Fight fight, FightObject fightObj, byte attackType) {
        if (fightObj == null || !fightObj.isPet()) {
            return null;
        }
        FightObject hostObj = fight.queryFightObject(fightObj.getHostId());
        if (hostObj == null) {
            return null;
        }
        PetFightObject pet = (PetFightObject) fightObj;
        List<PetBook> books = pet.getBooksBy(attackType);
        if (CollectionUtils.isEmpty(books)) {
            return null;
        }
        return books.get(new Random().nextInt(books.size()));
    }

    /**
     * 普通攻击
     */
    private void normalAttack(FightObject attacker, Fight fight) {
        attacker.setType(FightAction.PHYSICAL_ATTACK);
        attacker.setSkillId(FightAction.PHYSICAL_ATTACK);

        boolean isConfusion = attacker.isConfusion();
        /** 混乱状态可以对友方出手 如果不是混乱状态再检查其他的状态 */
        if (!isConfusion) {
            if (checkDeStatus(fight, attacker)) {
                return;
            }
        }
        /** 如果物攻目标是自己 需要置0 否则客户端卡死 */
        if (attacker.getId() == attacker.getTargetId()) {
            attacker.setTargetId(0);
        }

        FightObject fightTarget = fight.queryFightObject(attacker.getTargetId());
        // 法宝特殊技能效果--嘲讽攻击目标切换
        Object changeTarget = ArtifactSkillProcessor.getSkillProcessor(ArtifactSkillProcessor.SNEER_SKILL)
                .delayAction(fight, attacker);
        if (changeTarget != null) {
            fightTarget = (FightObject) changeTarget;
        }

        if (fightTarget == null || fightTarget.isFallDown()) {
            fightTarget = getPhysicTarget(attacker, fight);
            if (fightTarget == null || fightTarget.isFallDown()) {
//                logger.error("fight[{}], type[{}],没有取到存活目标===={}", fight.getId(), fight.getType(), attacker.getName());
                fightMessageService.sendNullAction(fight, attacker);
                return;
            }
            attacker.setTargetId(fightTarget.getId());
        }

        if (isConfusion) {
            List<FightObject> arrayList = getConfusionFightTargets(attacker, fight);
            if (arrayList.size() <= 0) {
//                logger.error("fight[{}], type[{}],没有取到存活目标===={}", fight.getId(), fight.getType(), attacker.getName());
                fightMessageService.sendNullAction(fight, attacker);
                return;
            }
            Random random = new Random();
            int index = random.nextInt(arrayList.size());
            fightTarget = arrayList.get(index);
            attacker.setTargetId(fightTarget.getId());
        }

        if (fightTarget.isFallDown()) {
//            logger.error("fight[{}], type[{}],没有取到存活目标===={}", fight.getId(), fight.getType(), attacker.getName());
            fightMessageService.sendNullAction(fight, attacker);
            return;
        }

        {
            /** 卸甲金葫只在物攻法攻时候判断效果是否能触发 */
            boolean gourdEffect = (Boolean) ArtifactType.GOURD.getEffect().trigger(fight, attacker);
            if (gourdEffect) {
                fight.makeTargetArtifactInvalid(attacker.getTargetId());
                ArtifactType.GOURD.getEffect().broadCast(fight, attacker);
            }
        }

        BattleUnit battleUnit = new BattleUnit(fight, attacker, fightTarget);
        battleUnit.triggerPhysic();

        // 天书--反击
        if (BookSkillProcessor.defenseTrigger(fightTarget, fight, BookSkillProcessor.FAN_JI)) {
            BookSkillProcessor.queryProcessor(BookSkillProcessor.FAN_JI).effect(fight, fightTarget, attacker);
        }

        checkOrderTarget(fight, Collections.singletonList(attacker.getTargetId()));

        if (fightTarget.isFallDown()) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.fallDown(fightTarget.getId(), 1));
            fight.onActorDie(fightTarget);

            checkGuessSuccess(fight);
        }
        if (attacker.isFallDown()) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.fallDown(attacker.getId(), 1));
            fight.onActorDie(attacker);
        }

        if(fightTarget.isSleep()){
            /**如果目标是昏睡状态 打一下就给状态清除*/
            fightTarget.setStatus(StatusConst.STATUS_SLEEP, 0);
            fightMessageService.sendFightAction(fight, fightTarget);
        }


        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(attacker.getId()));
    }

    /**
     * 混乱状态取目标
     */
    private List<FightObject> getConfusionFightTargets(FightObject fightObject, Fight fight) {
        List<FightObject> result = new ArrayList<>();
        List<FightObject> firstTargets = fightObject.isASide() ? fight.getListA() : fight.getListB();
        List<FightObject> secondTargets = fightObject.isASide() ? fight.getListB() : fight.getListA();

        for (FightObject target : firstTargets) {
            if (!target.isFallDown() && fightObject.getId() != target.getId()) {
                result.add(target);
            }
        }
        if (result.size() <= 0) {
            for (FightObject target : secondTargets) {
                if (!target.isFallDown() && fightObject.getId() != target.getId()) {
                    result.add(target);
                }
            }
        }
        return result;
    }

    /**
     * 使用物品
     */
    private void useItem(FightObject fightObject, Fight fight) {
        if (checkDeStatus(fight, fightObject)) {
            return;
        }
        if (canUseLifeItem(fight) && !(fightObject.isPlayer() || fightObject.isPet())) {
            // 给星君加血
            xinjunRecoverHp(fightObject, fight);
            return;
        }
        IoSession session = fightObject.getSession();
        if (session == null) {
            fightMessageService.sendNullAction(fight, fightObject);
//            logger.warn("fight[{}], type[{}], useItem {}", fight.getId(), fight.getType(), fightObject.getName());
            return;
        }
        Role attacker = SessionUtils.getRoleBySession(session);// Fixme 会报空 这里最好用主人Object里面的role
        FightObject target = fight.queryFightObject(fightObject.getTargetId());
        if (target == null) {
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }
        RoleEquip roleEquip = equipService.getRoleEquipByPos(attacker, fightObject.getSkillId());
        if (roleEquip == null) {
//            logger.error("战斗使用道具不存在。fight[{}], type[{}], useItem [{}], skillId:[{}]", fight.getId(), fight.getType(),
//                    fightObject.getName(), fightObject.getSkillId());
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }

        FightItemHandler itemHandler = FightItemHandler.queryHandler(roleEquip.getName());
        if (itemHandler == null) {
            fightMessageService.sendNullAction(fight, fightObject);
            return;
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(fightObject, 1, 0, 0));

        itemHandler.use(fight, fightObject, roleEquip);

        attacker.save();

        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));
    }

    /**
     * 给星君加血
     *
     * @param fightObject
     * @param fight
     * @return
     */
    private void xinjunRecoverHp(FightObject fightObject, Fight fight) {
        int hostId = fightObject.getHostId();
        if (fightObject.getCurrLife() < fightObject.getMaxLife() * 0.2) {
            fightObject.setTargetId(fightObject.getId());
        } else {
            FightObject hostObject = fight.queryFightObject(hostId);
            if (hostObject != null && hostObject.isFallDown()) {
                fightObject.setTargetId(hostObject.getId());
            } else {
                return;
            }
        }
        FightObject target = fight.queryFightObject(fightObject.getTargetId());
        int life = new Double(target.getMaxLife() * 0.2).intValue();
        if (life + target.getCurrLife() >= target.getMaxLife()) { // 加血循环次数不对 加血应该在外面
            life = target.getMaxLife() - target.getCurrLife();
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));
        /**
         * 出手动画
         */
        FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(fightObject, 1, 0, 0));
        FightMessageUtil.sendFightPackage(fight,
                fightMessageService.useItem(fightObject.getId(), target.getId(), 1002));
        FightMessageUtil.sendFightPackage(fight,
                fightMessageService.decreaseLife(fightObject.getId(), target.getId(), life, 0, 0));
        FightMessageUtil.sendFightPackage(fight,
                fightMessageService.updateTargetLife(target.getId(), target.getCurrLife()));
        if (target.isFallDown()) {// 如果目标死亡 并且 使用道具 或者加血技能就复活
            target.setCurrLife(target.getCurrLife() + life);// 加上道具所加的气血
            FightMessageUtil.sendFightPackage(fight, fightMessageService.revive(target.getId()));
        }
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));
    }

    /**
     * 防御
     */
    private void defense(FightObject fightObject, Fight fight) {
        if (checkDeStatus(fight, fightObject)) {
            return;
        }

        fightObject.getStatusMap().setv(String.valueOf(STATUS_DEFENSE), 1);// 设置一回合的防御状态
        FightMessageUtil.sendFightPackage(fight,
                fightMessageService.doActionStart((short) fight.getRound(), fightObject));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.fightShouting(fightObject, "防御"));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(fightObject, 0, 0, 0));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));
        fightMessageService.sendFightAction(fight, fightObject);
    }

    /**
     * 更新个人增益障碍状态
     */
    private void updateStatus(FightObject fightObject) {
        if (fightObject.isMonster()) {
            return;
        }
        IoSession oSession = fightObject.getSession();
        if (oSession == null) {
            return;
        }
        NutMap statusMap = fightObject.getStatusMap();
        if (statusMap.size() >= 1) {
            for (Map.Entry<String, Object> entry : statusMap.entrySet()) {
                if (entry.getKey().contains("a")) {
                    continue;
                }
                int value = (int) entry.getValue();
                if (value <= 0) {
                    switch (NumberUtil.intValue(entry.getKey())) {
                        case STATUS_PHY_POWER_UP: {
                            RespCombatUpdateImprovement respCombatUpdateImprovement = new RespCombatUpdateImprovement();
                            respCombatUpdateImprovement.setId(fightObject.getId());
                            List<FiedValue> list = new ArrayList<>();
                            respCombatUpdateImprovement.setList(list);
                            // 物伤
                            list.add(new FiedValue((short) 3, (byte) 3, 0));
                            // 法伤
                            list.add(new FiedValue((short) 10, (byte) 3, 0));
                            MessagePusher.pushMessage(oSession, respCombatUpdateImprovement);
                            break;
                        }
                        case STATUS_SPEED_UP: {
                            RespCombatUpdateImprovement respCombatUpdateImprovement = new RespCombatUpdateImprovement();
                            respCombatUpdateImprovement.setId(fightObject.getId());
                            List<FiedValue> list = new ArrayList<>();
                            respCombatUpdateImprovement.setList(list);
                            // 速度
                            list.add(new FiedValue((short) 14, (byte) 2, 0));
                            MessagePusher.pushMessage(oSession, respCombatUpdateImprovement);
                            break;
                        }
                        case STATUS_DEF_UP: {
                            RespCombatUpdateImprovement respCombatUpdateImprovement = new RespCombatUpdateImprovement();
                            respCombatUpdateImprovement.setId(fightObject.getId());
                            List<FiedValue> list = new ArrayList<>();
                            respCombatUpdateImprovement.setList(list);
                            // 速度
                            list.add(new FiedValue((short) 8, (byte) 3, 0));
                            MessagePusher.pushMessage(oSession, respCombatUpdateImprovement);
                            break;
                        }
                        case STATUS_DODGE_UP: {
                            RespCombatUpdateImprovement respCombatUpdateImprovement = new RespCombatUpdateImprovement();
                            respCombatUpdateImprovement.setId(fightObject.getId());
                            List<FiedValue> list = new ArrayList<>();
                            respCombatUpdateImprovement.setList(list);
                            // 闪避
                            list.add(new FiedValue((short) 15, (byte) 3, 0));
                            MessagePusher.pushMessage(oSession, respCombatUpdateImprovement);
                            break;
                        }

                    }
                }
                //没看懂这个逻辑。为什么等于0在更新。 先在这里加上嘲讽。  日后看看清风是怎么写的
                // 这个逻辑导致 除了辅助技能 所有的状态都无法显示持续回合
//                switch (Integer.parseInt(entry.getKey())){
//                    case STATUS_CHAOFENG: {
//                        RespCombatUpdateImprovement respCombatUpdateImprovement = new RespCombatUpdateImprovement();
//                        respCombatUpdateImprovement.setId(fightObject.getId());
//                        List<FiedValue> list = new ArrayList<>();
//                        respCombatUpdateImprovement.setList(list);
//                        // 闪避
//                        list.add(new FiedValue((short) STATUS_CHAOFENG, (byte)3, 0));
//                        MessagePusher.pushMessage(oSession, respCombatUpdateImprovement);
//                    }
//                }

            }
        }
    }

    /**
     * 法攻
     */
    private void magicAttack(FightObject attacker, Fight fight) {
        /** 检查出手方身上的 障碍状态 判断是否能出手 */
        if (checkDeStatus(fight, attacker)) {
            return;
        }
        RoleSkill roleSkill = attacker.getSkillBy(attacker.getSkillId());
        if (roleSkill.getName().equals("游说之舌")){
            roleSkill.setMana(1);
        }
        SkillAction skillAction = new SkillAction(fight, attacker, roleSkill);
        List<Integer> targetList = skillAction.pickUpTargets();
        if (targetList.size() <= 0) {
            fightMessageService.sendNullAction(fight, attacker);
            return;
        }
        FightObject mainTarget = fight.queryFightObject(attacker.getTargetId());

        if (mainTarget == null || mainTarget.isFallDown() || mainTarget.isASide() == attacker.isASide()) {
            mainTarget = fight.queryFightObject(targetList.get(0));
            /** 如果目标ID为0的情况下 就会出现在屏幕外面去了 */
            attacker.setTargetId(mainTarget.getId());
        }

        // 法宝特殊技能效果--嘲讽攻击目标切换
        Object changeTarget = ArtifactSkillProcessor.getSkillProcessor(ArtifactSkillProcessor.SNEER_SKILL)
                .delayAction(fight, attacker);
        if (changeTarget != null) {
            mainTarget = (FightObject) changeTarget;
            attacker.setTargetId(mainTarget.getId());
        }

        {
            /** 卸甲金葫只在物攻法攻时候判断效果是否能触发 */
            boolean gourdEffect = (Boolean) ArtifactType.GOURD.getEffect().trigger(fight, attacker);
            if (gourdEffect) {
                fight.makeTargetArtifactInvalid(attacker.getTargetId());
                ArtifactType.GOURD.getEffect().broadCast(fight, attacker);
            }
        }

        /** 只有宠物跟人物需要扣蓝 */
        if (attacker.isPlayer() || attacker.isPet()) {
            if (roleSkill.getMana() >= attacker.getCurrMana()) {
                IoSession session = attacker.getSession();
                if (session != null) {
                    RespMsg msg = new RespMsg();
                    msg.setMsg("当前法力不足，无法施放技能。");
                    MessagePusher.pushMessage(session, msg);

                }
                fightMessageService.sendNullAction(fight, attacker);
                return;
            }
            attacker.setCurrMana(attacker.getCurrMana() - roleSkill.getMana());
        }

        // 力魄千钧
        if (attacker.getSkillId() == 501) {
            liPoSkill(fight, attacker, targetList);
            return;
        }

        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), attacker));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.updateObjectInfo(attacker));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.fightShouting(attacker, "法攻"));

        // 法攻执行效果
        skillAction.doMagicEffect();

        checkOrderTarget(fight, targetList);

        /** 番天印能再出发一次同级或低一阶的法攻，且不扣蓝 人物倒地不触发 */
        if (!attacker.isFallDown()) {
            if (!(roleSkill.isAssistSkill() || roleSkill.getType() == 147)) {// 不是辅助或者障碍技能才触发
                ArtifactType.STAMPER.getEffect().trigger(fight, attacker, roleSkill);
            }
        }
    }

    /**
     * 力魄千钧
     */
    private void liPoSkill(Fight fight, FightObject attacker, List<Integer> targetList) {
        RoleSkill roleSkill = attacker.getSkillBy(attacker.getSkillId());
        SkillAction skillAction = new SkillAction(fight, attacker, roleSkill);
        skillAction.setSkillTargets(targetList);
        skillAction.liPoEffect();
    }

    /**
     * 下一回合
     */
    public void nextRound(Role role, Fight fight) {
        FightObject myObject = fight.queryFightObject(role.getRoleId());
        if (myObject == null) {
            return;
        }
        NutMap nutMap = myObject.getRoundController();
        int currRound = fight.getRound();
        int time = nutMap.getInt(currRound+"");
        nutMap.setv(currRound+"",time+1);
        if (nutMap.getInt(currRound+"") > 5){
            IoSession session = SessionUtils.getSession(role.getRoleId());
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("检测到使用加速器，三秒后会掉线！"));
            log.error("战斗异常封闭角色=={}=={}=={}",role.getRoleId(),role.getName(),Json.toJson(nutMap,JsonFormat.compact()));
            SpringUtils.getBean(ServerService.class).getScheduledExecutorService().schedule(new Runnable() {
                @Override
                public void run() {
                    session.closeNow();
                }
            },3, TimeUnit.SECONDS);
            return;
        }
//        if (myObject.isRequested(fight.getRound(), true)) {
//            logger.error("fight[{}], type[{}], 回合重复[{}]", fight.getId(), fight.getType(), fight.getRound());
//            return;
//        }

        /**定时发送面板或者结束战斗*/
//        if (fight.getNextRoundTimer() == null || fight.getNextRoundTimer().isCancelled()
//                || fight.getNextRoundTimer().isDone()) {
//            NextRoundTask timeOut = new NextRoundTask(fight);
//            ScheduledFuture<?> timeOutTask = SchedulerManager.getInstance().schedule(timeOut, 30000);
//            fight.setNextRoundTimer(timeOutTask);
//        }

        fightExecutorService.addFightTask(fight, new FightingTask() {
            @Override
            public void run() {
                if (fight.isOver()) {
                    quitFight(fight);
                } else {
//                    logger.error("fight[{}], type[{}], 进入下一回合[{}]", fight.getId(), fight.getType(), fight.getRound());
                    fightMessageService.sendPanel(fight);
                    fightMessageService.sendPanel(myObject,fight);
                    checkRoundShouting(fight, role);
                }
            }
        });

    }

    /**
     * 进战斗循环发送
     */
    public void whileSendStart(Fight fight) {
        //log.info("进入战斗循环发送："+fight.getAllFightObjects().size());
        for (FightObject fightObject : fight.getAllFightObjects()) {
            IoSession session = fightObject.getSession();
            sendXingBook(fight, fightObject);
            if (session == null) {
                continue;
            }
            if (fightObject.getFightPetId() > 0) {// 准备加载宠物天书
                FightObject petObject = fight.queryFightObject(fightObject.getFightPetId());
                if (petObject != null) {
                    sendPetBook(session, fight, petObject);
                    RespRefreshPetList respRefreshPetList = new RespRefreshPetList();
                    RefreshPet refreshPet = new RefreshPet();
                    List<RefreshPet> refreshPets = new ArrayList<>();
                    refreshPets.add(refreshPet);
                    refreshPet.setPetId(petObject.getId());
                    respRefreshPetList.setPetList(refreshPets);
                    MessagePusher.pushMessage(session, respRefreshPetList);
                }
            }

            RespFightClearTime respFightClearTime = new RespFightClearTime();
            respFightClearTime.setRoleId(fightObject.getId());
            MessagePusher.pushMessage(session, respFightClearTime);
            MessagePusher.pushMessage(session, fightMessageService.round(fight.getRound(), 0));
            //修改进入战斗 显示两次第一回合。
            //观战没反应。是不是这里的问题。恢复一下
            if(fightObject.isPlayer()){
                Role role = SessionUtils.getRoleBySession(session);
                checkRoundShouting(fight, role);
                MessagePusher.pushMessage(session, fightMessageService.mianban(fight.getRound()));

                //发送阵法特效
            }

            // 发送自动战斗设置
            MessagePusher.pushMessage(session, fightMessageService.selfAuto(fightObject, fight));
        }
        ZhenFaService zhenfaService = SpringUtils.getBean(ZhenFaService.class);
        //发送阵法相关
        List<FightObject> listA = fight.getListA();
        List<FightObject> listB = fight.getListB();
        ZhenFaInfo zhenFaInfoA = ZhenFaService.getChangeCardZhen(listA);
        ZhenFaInfo zhenFaInfoB = ZhenFaService.getChangeCardZhen(listB);
        for (FightObject fightObject : listA) {
            if(zhenFaInfoA != null){
                ZhenFaService.sendZhenDaEffect(fight,fightObject,zhenFaInfoA.getPolar(),1);
                ZhenFaService.sendZhenDaEffect(fight,fightObject,zhenFaInfoA.getPolar(),2);
                Role role = fightObject.getRole();
                if(teamService.isTeamLeader(role)){
                    FightMessageUtil.sendFightPackage(fight,new RespAttackSkillLightEffect(fightObject.getId(),(short)0,4,"阵眼"));
                }else{
                    FightMessageUtil.sendFightPackage(fight,new RespAttackSkillLightEffect(fightObject.getId(),(short)0,4,zhenFaInfoA.getZhenfa()));
                }
            }
            zhenfaService.sendBattleArray(fight,fightObject,zhenFaInfoA,zhenFaInfoB,true);
        }
        for (FightObject fightObject : listB) {
            if(zhenFaInfoB != null){
                ZhenFaService.sendZhenDaEffect(fight,fightObject,zhenFaInfoB.getPolar(),1);
                ZhenFaService.sendZhenDaEffect(fight,fightObject,zhenFaInfoB.getPolar(),2);
                Role role = fightObject.getRole();
                if(teamService.isTeamLeader(role)){
                    FightMessageUtil.sendFightPackage(fight,new RespAttackSkillLightEffect(fightObject.getId(),(short)0,4,"阵眼"));
                }else{
                    FightMessageUtil.sendFightPackage(fight,new RespAttackSkillLightEffect(fightObject.getId(),(short)0,4,zhenFaInfoB.getZhenfa()));
                }
            }
            zhenfaService.sendBattleArray(fight,fightObject,zhenFaInfoB,zhenFaInfoA,false);
        }
    }

    /**
     * 查看战斗增益
     */
    public void checkExtraInfo(Role role, ReqGeneralNotify reqGeneralNotify) {
        int id = Integer.parseInt(reqGeneralNotify.getStatus());
        Fight fight = getFightByRoleId(role.getRoleId());
        if (fight != null) {
            FightObject fightObject = fight.queryFightObject(id);
            if (fightObject == null) {
                return;
            }
            List<FiedValue> list = FieldUtils.listFightExtra(fightObject);
            RespCombatStatusInfo respCombatStatusInfo = new RespCombatStatusInfo();
            respCombatStatusInfo.setId(id);
            respCombatStatusInfo.setStatusType(reqGeneralNotify.getString());
            respCombatStatusInfo.setList(list);
            respCombatStatusInfo.setIsCanUseHYJJ((byte) 1);
            respCombatStatusInfo.setZhenfaPolar((byte)fightObject.getZhenfaPolar());
            MessagePusher.pushMessage(role, respCombatStatusInfo);
        }
    }




    /**
     * 获得角色用于战斗的队伍
     */
    public Team getRoleFightTeam(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        if (!teamService.isInTeam(role)) {
            ArrayList<Member> arrayList = new ArrayList<>();
            Member member = Member.valueOf(role);
            arrayList.add(member);
            team = new Team();
            team.setList(arrayList);
            team.setShouhus(SpringUtils.getBean(GuardService.class).getGuardMembers(role, 5 - team.getList().size()));
        }

        return team;
    }

    /**
     * 玩家是否在战斗中
     */
    public boolean isInFight(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        List<Member> memberList = Collections.emptyList();
        if (team != null) {
            memberList = team.getList();
        }
        return isInFight(role, memberList);
    }

    /**
     * 玩家是否在战斗中
     */
    private boolean isInFight(Role role, List<Member> list) {
        if (role != null) {// 判断队长战斗状态
            Fight fight = getFightByRoleId(role.getRoleId());
            if (fight != null && !fight.isOver()) {
                return true;
            }
        }
        if (list != null) {
            for (Member member : list) {// 判断队员战斗状态
                Fight fight = getFightByRoleId(member.getRoleId());
                if (member.isInTeam() && fight != null && !fight.isOver()) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 取目标列表
     */
    public List<Integer> getTargetListNew(FightObject fightObject, int maxNum, Fight fight) {
        RoleSkill skill = fightObject.getSkillBy(fightObject.getSkillId());
        if (skill == null) {
//            logger.error("{}技能不存在", fightObject.getSkillId());
            return Collections.emptyList();
        }
        // 力破，十字架技能选择器
        if (fightObject.getSkillId() == 501) {
            return SkillTargetPicker.getCrossAttackTarget(fight, fightObject, maxNum);
        }
        if (skill.isAssistSkill()) {
            // 辅助技能 只能选择己方
            return SkillTargetPicker.getAssistTarget(fight, fightObject, maxNum);
        } else {
            return SkillTargetPicker.getRandomAttackTarget(fight, fightObject, maxNum);
        }
    }

    /**
     * 取物攻目标
     */
    public FightObject getPhysicTarget(FightObject fightObject, Fight fight) {
        FightObject target = fight.queryFightObject(fightObject.getTargetId());
        /** 不用判断是不是己方 要判断是不是自己 是自己客户端会报错 */
        if (target != null && !target.isFallDown() && fightObject.getId() != target.getId()) {
            return target;
        }
        List<FightObject> selfList = fight.getTargetSide(fightObject.getId());
        selfList = selfList.stream().filter(obj -> !obj.isFallDown()).collect(Collectors.toList());
        if (selfList.size() <= 0) {
//            logger.error("物攻目标出错={}", new IllegalArgumentException());
            return null;
        }
        Random random = new Random();
        int index = random.nextInt(selfList.size());
        return selfList.get(index);
    }

    /**
     * 退出战斗
     */
    public void quitFight(Fight fight) {
        fight = getFight(fight.getId());
        if (fight == null) {
//            logger.error("退出战斗的战场为空");
            return;
        }
        for (FightObject fightObject : fight.getAllFightObjects()) {
//            logger.error("正常战斗结束=={}",fight.getType());
            quiteFight(fight, fightObject, true);
        }

        clearFight(fight);
    }

    /**
     * 退出战斗
     */
    public void quiteFight(Fight fight, FightObject fightObject, boolean isReward) {
        if (!fightObject.isPlayer()) {
            return;
        }
//        try {
//            throw new Exception();
//        }catch (Exception e){
//            logger.error("退出战斗=={}",isReward,e);
//        }
        Role role = fightObject.getRole();
        role.setPrevFightEndTime(System.currentTimeMillis());

        Integer fightId = FightExecutorService.FIGHT_ROOMS.get(fightObject.getId());
        if (fightId != null && fight.getId() == fightId) {
            FightExecutorService.FIGHT_ROOMS.remove(fightObject.getId());
            FightExecutorService.FIGHT_ROOMS.remove(fightObject.getFightPetId());
            FightExecutorService.PETID_ROLEID.remove(fightObject.getFightPetId());
        }

        ThreadLocalUtil.addLocalTask(role, () -> playerQuitFight(fight, fightObject, isReward, role));
    }
    private void playerQuitFight(Fight fight, FightObject fightObject, boolean isReward, Role role) {
        try {
            FightObject currPetObject = fight.queryFightObject(fightObject.getFightPetId());
            Pet currPet = null;
            if (currPetObject != null) {
                currPet = currPetObject.getPet();
            } else {
                /** 当前参战宠物已经死亡了，获得设置的出战宠物 */
                currPet = SpringUtils.getPetService().getPetById(role.getPetBox().getFightPetId(), role);
            }
            role.pushTempCache("fight_current_pet_id", (currPet != null ? currPet.getId() : 0));

            MessagePusher.pushMessage(role, fightMessageService.round(fight.getRound() + 1, 0));
            RespCombatAction combatAction = new RespCombatAction();
            combatAction.setRound((short) (fight.getRound() + 1));
            combatAction.setAction(FightAction.SPECIAL);
            MessagePusher.pushMessage(role, combatAction);

            role.setLastDead(fightObject.getCurrLife()<=0?0:1);
            if (isReward) {
                //sendReward(fight, role, currPet);
                sendBossReward(role,fight,currPet);
            }
            fireEndEvent(fight, role, currPet);

            RespCombatEndAction endAction = new RespCombatEndAction();
            MessagePusher.pushMessage(role, endAction);

            for (FightObject fightActor : fight.getAllFightObjects()) {
                combatAction = new RespCombatAction();
                combatAction.setRound((short) (fight.getRound() + 1));
                combatAction.setAction(FightAction.CHECK_STATUS);
                int id = fightActor.getId();
                combatAction.setAttacker_id(id);
                combatAction.setVictim_id(id);
                MessagePusher.pushMessage(role, combatAction);
                if (fightActor != null) {
                    RespCombatUpdateStatus respCombatUpdateStatus = new RespCombatUpdateStatus();
                    respCombatUpdateStatus.setTargetId(id);
                    MessagePusher.pushMessage(role, respCombatUpdateStatus);
                }
                endAction = new RespCombatEndAction();
                endAction.setId(id);
                MessagePusher.pushMessage(role, endAction);
            }
            resetAfterLeaveFight(fight, fightObject);
        } catch (Exception e) {
            log.error("退出战斗报错了,战场ID=[{}],角色名=[{}],错误信息[{}]", fight.getId(), fightObject.getName(), e);
        } finally {
            Set<Integer> petSet = role.getPetBox().equippedPets(role);
            RespCombatAction respCombatAction = new RespCombatAction();
            respCombatAction.setRound((short) (fight.getRound() + 1));
            MessagePusher.pushMessage(role, respCombatAction);

            for (Integer petId : petSet) {
                if (role.getPetBox().getFightPetId() == petId) {
                    RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
                    respSetCurrentPet.setPetId(petId);
                    respSetCurrentPet.setStatus((short) 1);
                    MessagePusher.pushMessage(role, respSetCurrentPet);
                } else if (role.getPetBox().getSupplyPetId() == petId) {
                    RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
                    respSetCurrentPet.setPetId(petId);
                    respSetCurrentPet.setStatus((short) 2);
                    MessagePusher.pushMessage(role, respSetCurrentPet);
                } else {
                    RespSetFightPetStatus respSetFightPetStatus = new RespSetFightPetStatus();
                    respSetFightPetStatus.setRoleId(petId);
                    MessagePusher.pushMessage(role, respSetFightPetStatus);
                }
            }
            RespCombatEndAction endAction = new RespCombatEndAction();
            MessagePusher.pushMessage(role, endAction);

            RespCombatAction combatAction = new RespCombatAction();
            combatAction.setRound((short) (fight.getRound() + 1));
            MessagePusher.pushMessage(role, combatAction);
            RespCombatEndAction RespCombatEndAction = new RespCombatEndAction();
            MessagePusher.pushMessage(role, RespCombatEndAction);

            RespEndCombat respEndCombat = new RespEndCombat();
            MessagePusher.pushMessage(role, respEndCombat);
            broadcastService.sendUpdateAppear(role);
            broadcastService.sendTitleInfo(role);
            roleService.sendAutoSet(role);
        }
    }

    /**
     * 当前回合是否所有玩家都请求面板
     */
    private boolean allPlayersDoActionCurrRound(Fight fight) {
        double requestNum = 0;
        double totalNum = 0;
        for (FightObject fightObject : fight.getAllFightObjects()) {
            if (fightObject.isPlayer()) {
                totalNum++;
                if (fightObject.isRequested(fight.getRound(), false)) {
                    requestNum++;
                } else {
                    /** 如果没有出手的再判断是不是掉线玩家 */
                    IoSession session = fightObject.getSession();
                    if (session == null) {
                        requestNum++;
                    } else {
                        /** 在线的需要判断一下是不是在后台 */
                        String clientStatus = SessionManager.INSTANCE.getSessionAttr(session,
                                SessionProperties.CLIENT_STATUS, String.class);
                        if (clientStatus.equals(CLIENT_INACTIVE)) {
                            requestNum++;
                        }
                    }
                }
            }
        }
        return requestNum == totalNum;
    }

    /**
     * 进入战斗发送宠物天书
     */
    private void sendPetBook(IoSession mySession, Fight fight, FightObject petObject) {
        Role role = SessionUtils.getRoleBySession(mySession);
        PetBook petBook = getRandomBook(role, petObject.getId());
        if (petBook == null) {
            return;
        }
        RespFightBook respFightBook = new RespFightBook();
        respFightBook.setPetId(petObject.getId());
        respFightBook.setIcon(petBook.getFightIcon());
        for (FightObject fightObject : fight.getAllFightObjects()) {
            if (fightObject.isPlayer()) {
                IoSession session = fightObject.getSession();
                MessagePusher.pushMessage(session, respFightBook);
            }
        }
    }

    /**
     * 星官的天书
     *
     * @param fight
     * @param petObject
     */
    private void sendXingBook(Fight fight, FightObject petObject) {
        if (petObject.getBossSet() instanceof Xing) {
            RespFightBook respFightBook = new RespFightBook();
            Random random = new Random();
            respFightBook.setPetId(petObject.getId());
            int index = random.nextInt(equipService.names.length);
            respFightBook.setIcon(bookService.getFightBookIcon(equipService.names[index]));
            for (FightObject fightObject : fight.getAllFightObjects()) {
                if (fightObject.isPlayer()) {
                    IoSession session = fightObject.getSession();
                    MessagePusher.pushMessage(session, respFightBook);
                }
            }
        }
    }

    /**
     * 进战斗取随机天书
     */
    public PetBook getRandomBook(Role role, int petId) {
        Map<Integer, PetBook> hashMap = role.getPetBox().getPetBooks(petId);
        if (hashMap.size() == 0) {
            return null;
        }
        List<PetBook> books = new ArrayList<>();
        for (Map.Entry<Integer, PetBook> entry : hashMap.entrySet()) {
            books.add(entry.getValue());
        }
        return books.get(new Random().nextInt(books.size()));
    }

    /**
     * 出手
     */
    public void doAction(ReqFightDoAction request) {
        if (request.getType() == 0) {
            request.setType(1);
            request.setTargetId(request.getAttackerId());
        } else if (request.getType() == 2 || request.getSkillId() == 501) {
            if (request.getAttackerId() == request.getTargetId()) {
                request.setTargetId(0);
            }
        }
        int hostId = getHostId(request.getAttackerId());
        Fight fight = getFightByRoleId(request.getAttackerId());
        if (fight == null) {
            log.info("战场已经销毁");
            return;
        }
        try {
            fightExecutorService.addFightTask(fight, new FightingTask() {
                @Override
                public void run() {
                    fightDoAction(request, hostId, fight);
                }
            });
        } catch (Exception e) {
            log.info("战斗出手报错了战场ID[{}]出手id[{}}{}{}{}", fight.getId(), request.getAttackerId(), e.getMessage(),
                    e.getStackTrace(), e);
        }
    }

    /**
     * 出手动作
     */
    private void fightDoAction(ReqFightDoAction req, int hostId, Fight fight) {
        if (fight.isOver()) {
            log.info("战斗[{}]已经结束，无法出手", fight.getId());
            return;
        }
        // 更新出手状态
        FightObject fightObject = fight.queryFightObject(req.getAttackerId());
        if (fightObject == null) {
            log.info("未找到自己的战场对象={}", req.getAttackerId());
            return;
        }
        IoSession session = fightObject.getSession();
        if (req.getType() == FightAction.CANCEL) {
            /** 重置出手只能宠物走进来 这时候还没有更新宠物出手状态 所以只用重置人物的出手就行 */
            RespCombatCommandAccepted respCombatCommandAccepted = new RespCombatCommandAccepted();
            respCombatCommandAccepted.setId(hostId);
            MessagePusher.pushMessage(session, respCombatCommandAccepted);
            resetDoActionStatus(fight, req);
            return;
        }

        if (fightObject.isPlayer() && req.getType() == FightAction.SELECT_PET && req.getSkillId() == 0) {
            Role role = fightObject.getRole();
            int petId = req.getTargetId();
            Pet pet = SpringUtils.getPetService().getPetById(petId, role);
            PetObject petSet = null;
            if (pet != null) {
                petSet = PetDataPool.getPetObject(pet.getName());
            }
            if (pet == null || pet.getLevel() - role.getLevel() > 15 || petSet == null
                    || petSet.getLevel_req() > role.getLevel() || pet.getId() == fightObject.getFightPetId()) {
                RespCombatCommandAccepted respCombatCommandAccepted = new RespCombatCommandAccepted();
                respCombatCommandAccepted.setId(req.getAttackerId());
                MessagePusher.pushMessage(role, respCombatCommandAccepted);
                resetDoActionStatus(fight, req);
                return;
            }
            RespConfirm respConfirm = new RespConfirm();
            respConfirm.setTips("是否确认召唤#R" + pet.getName() + "#n出战？");
            respConfirm.setConfirm_type("select_pet");
            MessagePusher.pushMessage(session, respConfirm);

            role.setConfirm(new PetFightConfirm(pet.getId(), fightObject.getFightPetId()));
            return;
        }

        /** 判断当前回合是否出手 */
        if (fightObject.isCompleted(fight.getRound(), false)) {
            return;
        }
        /**
         * 记录自动出手类型 自动战斗使用
         */
        if (req.getType() == FightAction.DEFENSE || req.getType() == FightAction.PHYSICAL_ATTACK
                || req.getType() == FightAction.CAST_MAGIC) {
            fightObject.setAutoTarget(req.getTargetId());
            fightObject.setTargetId(req.getTargetId());
        }

        updateDoActionStatus(fight, req.getAttackerId(), req.getTargetId(), req.getType(), req.getSkillId());

        /** 怪物出手 */
        monsterAI(fight);

        FightObject petObject = fight.queryFightObject(fightObject.getFightPetId());
        if (!fightObject.isPet() && petObject == null) {
            // 如果没有带宠物,自己出手后就清除时钟
            ArrayList<Message> messages = new ArrayList<>();
            messages.add(fightMessageService.fightAction(fightObject));
            messages.add(fightMessageService.clearClock(req.getAttackerId()));
            // true A方发送 false B方发送
            FightMessageUtil.sendFightPackage(fight, messages, fightObject.isASide());
        } else if (hostId > 0) {
            // 如果带了宠物,宠物出手后就清除时钟
            ArrayList<Message> messages = new ArrayList<>();
            FightObject hostObject = fight.queryFightObject(hostId);
            messages.add(fightMessageService.fightAction(hostObject));
            messages.add(fightMessageService.fightAction(fightObject));
            messages.add(fightMessageService.clearClock(hostId));
            FightMessageUtil.sendFightPackage(fight, messages, fightObject.isASide());
        }

        try {
            roundAction(fight);
        } catch (Exception e) {
            //LoggerUtils.error("", e);
        }
    }

    private void roundAction(Fight fight) {
        if (!fight.isStartFight()) {
            return;
        }
        /**战斗开始 清除战场定时*/
        fight.cancelTask(fight.getTimeOutTask());
        /** 回合开始的时候掉血和加血 */
        for (FightObject fightObject : fight.getAllFightObjects()) {
            // 舍生取义回血
            int sheShenRecove = fightObject.getStatusScore(STATUS_SHEN_SHE_QU_YI);
            if (sheShenRecove > 0) {
                if (fightObject.isFallDown()) {// 复活动画
                    FightMessageUtil.sendFightPackage(fight, fightMessageService.revive(fightObject.getId()));
                }
                fightObject.setCurrLife(fightObject.getCurrLife() + sheShenRecove);
                fightObject.removeStatus(STATUS_SHEN_SHE_QU_YI);
            }

            NutMap statusMap = fightObject.getStatusMap();
            fightObject.pushTempCache("dead", fightObject.isFallDown());
            if (statusMap.getInt(String.valueOf(STATUS_RECOVER_LIFE), 0) != 0) {
                int recoverValue = statusMap.getInt(STATUS_RECOVER_LIFE + "value");
                if (recoverValue > 0) {
                    fightObject.pushTempCache("recover", true);
                    if (recoverValue > fightObject.getMaxLife() - fightObject.getCurrLife()) {
                        recoverValue = fightObject.getMaxLife() - fightObject.getCurrLife();
                    }
                    fightObject.pushTempCache("recoverLife", recoverValue);
                    fightObject.setCurrLife(fightObject.getCurrLife() + recoverValue);
                    if (fightObject.getMaxLife() < fightObject.getCurrLife()) {
                        fightObject.setCurrLife(fightObject.getMaxLife());
                    }
                }
            }
            fightObject.pushTempCache("alive", !fightObject.isFallDown());
            if (statusMap.getInt(String.valueOf(STATUS_POISON), 0) != 0) {
                fightObject.pushTempCache("poison", true);
                int poisonValue = statusMap.getInt(STATUS_POISON + "value");
                if (poisonValue < 1) {
                    poisonValue = 1;
                } else if (poisonValue > fightObject.getCurrLife()) {
                    poisonValue = fightObject.getCurrLife();
                }
                fightObject.pushTempCache("poisonValue", poisonValue);

                fightObject.setCurrLife(fightObject.getCurrLife() - poisonValue);
                if (fightObject.isFallDown()) {
                    boolean revive = FightRateUtil.petCanRevive(fightObject);
                    fightObject.pushTempCache("revive", revive);
                }
                fightObject.pushTempCache("poisonDead", fightObject.isFallDown());
            }
        }

        for (FightObject fightObject : fight.getAllFightObjects()) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.checkStatusStart(fight.getRound(), fightObject.getId()));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.getStatusMessages(fightObject));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));
        }

        /** DEBUFF掉血或者BUFF加血 */
        for (FightObject fightObject : fight.getAllFightObjects()) {
            boolean poisonDead = fightObject.getTempCache("poisonDead", false);
            boolean dead = fightObject.getTempCache("dead", false);
            if (dead || poisonDead) {
                boolean revive = fightObject.getTempCache("revive", false);
                if (fightObject.isMonster() && !(fightObject.getBossSet() instanceof Xing)) {
                    fight.removeFightObject(fightObject);
                } else if (revive && fightObject.isPet()) {
                    fight.removeFightObject(fightObject);
                    FightObject hostObject = fight.queryFightObject(fightObject.getHostId());
                    if (hostObject != null && hostObject.isPlayer()) {
                        supplyPet(fight, fightObject, hostObject);
                    }
                }
            }
            fightObject.getTempCache().clear();
        }

        FightMessageUtil.sendFightPackage(fight, fightMessageService.start(fight.getRound()));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.end());

        for (FightObject fightObject : fight.getAllFightObjects()) {
            int actorId = fightObject.getId();
            FightMessageUtil.sendFightPackage(fight, fightMessageService.coreStart(fight.getRound(), actorId));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.coreStart(fight.getRound(), actorId));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(actorId));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(actorId));
        }


        actionStart(fight, fight.getAllFightObjects());

        if (fight.getRound() >= fight.getMaxRound()) {
            log.error("最大回合数=={}",fight.getMaxRound());
            for (FightObject fightObject : fight.getAllFightObjects()) {
                quiteFight(fight, fightObject, false);
            }
            clearFight(fight);
            return;
        }

        // 回合结束后触发玩家金蛟剪法宝效果
        checkScissorsArtifactEffect(fight, fight.getListA());
        checkScissorsArtifactEffect(fight, fight.getListB());

        fight.setRound(fight.getRound() + 1);
        besure(fight);
        SpringUtils.getBean(SuperBossHandler.class).checkFight(fight);

        /** 状态回合检查 */
        for (FightObject fightObject : fight.getAllFightObjects()) {
            FightMessageUtil.sendFightPackage(fight,
                    fightMessageService.checkStatusStart(fight.getRound(), fightObject.getId()));
            NutMap statusMap = fightObject.getStatusMap();
            for (Map.Entry<String, Object> entry : statusMap.entrySet()) {
                if (entry.getKey().contains("value")) {
                    int poisonValue = statusMap.getInt(STATUS_POISON + "value");
                    int recoverLife = statusMap.getInt(STATUS_RECOVER_LIFE + "value");
                    if (poisonValue > 0) {
                        statusMap.put(STATUS_POISON + "value", poisonValue / 2);
                    }
                    if (recoverLife > 0) {
                        statusMap.put(STATUS_RECOVER_LIFE + "value", recoverLife / 2);
                    }
                    continue;
                }

                // 自定义的状态不主动修改值
                if (NumberUtil.intValue(entry.getKey()) > 1000) {
                    continue;
                }

                int value = (int) entry.getValue();
                value--;
                if (value <= 0) {
                    value = 0;
                }
                if (fightObject.isFallDown() && entry.getKey().equals(String.valueOf(STATUS_RECOVER_LIFE))
                        && value > 0) {
                    value = 1;
                }
                statusMap.put(entry.getKey(), value);
            }
            updateStatus(fightObject);// 更新角色战斗增益
            FightMessageUtil.sendFightPackage(fight, fightMessageService.sendFightObjectStatus(fightObject));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));
        }

        /** 一回合完成,更新出手状态为假 */
        for (FightObject fightObject : fight.getAllFightObjects()) {
            fightObject.setTargetId(0);
            fightObject.setDoAction(false);
        }
    }

    @Autowired
    ServerService serverService;

    public void besure(Fight fight){
        // 添加定时器
        int fightId = fight.getId();
        int currRound = fight.getRound();
        serverService.getScheduledExecutorService().schedule(new Runnable() {
            @Override
            public void run() {
                Fight temp = getFight(fightId);
                if (temp != null && currRound == temp.getRound()) {
                    fightExecutorService.addFightTask(temp, new FightingTask() {
                        @Override
                        public void run() {
                            try {
                                ShiDaoHandler shiDaoHandler = SpringUtils.getBean(ShiDaoHandler.class);
                                for (FightObject fightObject : fight.getAllFightObjects()) {
                                    log.info("timer定时器结束战斗=={}=={}",currRound,fightObject.getName());
                                    Role tempRole = fightObject.getRole();
                                    if (tempRole == null){
                                        break;
                                    }
                                    if (shiDaoHandler.isInShiDaoMap(tempRole)) {
                                       log.info("回合超时退出=={}",tempRole.getName());
                                        quiteFight(fight, fightObject, true);
                                    }else if (fight.getType() == Const.fightType_shuadao
                                            ||fight.getType() == Const.fightType_shidao_pk
                                            ||Const.fightType_shidao_yuanmo==fight.getType()){
                                        log.info("回合超时退出=={}",tempRole.getName());
                                        quiteFight(fight, fightObject, true);
                                    }else {
                                        quiteFight(fight, fightObject, false);
                                    }

                                }
                                clearFight(fight);
                                log.info("timer定时器结束战斗=={}",currRound);
                            }catch (Exception e){
                                log.info("timer定时器结束战斗==报错",e);
                            }
                        }
                    });
                }
                log.info("回合定时器=={}=={}",currRound,(fightId));
            }
        },90, TimeUnit.SECONDS);
    }

    private void checkScissorsArtifactEffect(Fight fight, List<FightObject> listA) {
        for (FightObject fightObject : listA) {
            if (fightObject.isPlayer()) {
                boolean effect = (boolean) ArtifactType.SCISSORS.getEffect().trigger(fight, fightObject);
                if (effect) {
                    // 每回合一方最多只有一把剪刀生效
                    break;
                }
            }
        }
    }

    /**
     * 宠物掠阵
     *
     * @param fight
     * @param fightObject
     * @param hostObject
     */
    public void supplyPet(Fight fight, FightObject fightObject, FightObject hostObject) {
        int supplyPetId = hostObject.getRole().getPetBox().getSupplyPetId();
        if (supplyPetId <= 0 || fight.petDeadOnce(supplyPetId)) {
            return;
        }
        Pet pet = SpringUtils.getPetService().getPetById(supplyPetId, hostObject.getRole());
        if (pet == null) {
            return;
        }
        Pair<Message, Message> messages = fightMessageService.supplyPetPackage(fight, hostObject);
        if (messages != null) {
            sendPairFightMessage(fight, fightObject, messages);
            FightMessageUtil.sendFightPackage(fight,
                    fightMessageService.fightShouting(fight.queryFightObject(supplyPetId), "出战"));
            PetBook petBook = getRandomBook(hostObject.getRole(), supplyPetId);
            if (petBook != null) {
                FightMessageUtil.sendFightPackage(fight,
                        fightMessageService.summonPetBookEffect(supplyPetId, petBook.getFightIcon()));
            }
            if (hostObject.getAutoFight() == 1) {
                RespSyncMessage respSyncMessage = new RespSyncMessage();
                respSyncMessage.setCode((short) 32985);
                respSyncMessage.setMsg(AsktaoUtil.getMessageBody(fightMessageService.selfAuto(hostObject, fight)));
                MessagePusher.pushMessage(hostObject.getRole(), respSyncMessage);
            }
        }
    }

    private void sendPairFightMessage(Fight fight, FightObject fightObject, Pair<Message, Message> messages) {
        Message first = messages.getFirst();
        Message second = messages.getSecond();
        if (fight.getType() == Const.fightType_PK || fight.getType() == Const.fightType_shidao_pk) {
            if (fightObject.isASide()) {
                FightMessageUtil.sendFightPackage(fight, first, true);
                FightMessageUtil.sendFightPackage(fight, second, false);
            } else {
                FightMessageUtil.sendFightPackage(fight, second, true);
                FightMessageUtil.sendFightPackage(fight, first, false);
            }
        } else {
            FightMessageUtil.sendFightPackage(fight, first, true);
        }
    }

    private void actionStart(Fight fight, List<FightObject> list) {
        if (fight.isOver()) {
            return;
        }
        List<FightObject> copyFightObjs = new ArrayList<>(list);
        Collections.sort(copyFightObjs);

        Iterator<FightObject> it = copyFightObjs.iterator();

        while (it.hasNext()) {
            FightObject next = it.next();
            it.remove();
            if (next == null) {
                continue;
            }

            if (next.isFallDown()) {
                if (next.getType() != 7) {
                    continue;
                }
            }
            try {
                /** 判断当前回合是否出手 */
                if (next.isCompleted(fight.getRound(), true)) {
                    continue;
                }
//                logger.info("fight[{}], type[{}]出手，出手人[{}]，当前回合数[{}]", fight.getId(), fight.getType(), next,
//                        fight.getRound());
                doActionResult(next, fight);
            } catch (Exception e) {
                fightMessageService.sendNullAction(fight, next);
                log.error("fight[" + fight.getId() + "]出错", e);
//                logger.error("fight[{}], type[{}]出手，出手出错, 出手人[{}]，目标[{}]，技能ID={},当前回合数[{}]", fight.getId(),
//                        next.getType(), next.getId(), next.getTargetId(),
//                        next.getSkillId(), fight.getRound());
            }

            break;
        }

        if (copyFightObjs.size() > 0) {
            actionStart(fight, copyFightObjs);
        }
    }

    private void doActionResult(FightObject attacker, Fight fight) {
        int type = attacker.getType();
        if (attacker.isFallDown()) {
            if (type != FightAction.FLEE) {
                return;
            }
        }
//        /** 卸甲金葫只在物攻法攻时候判断效果是否能触发 */
//        if (type == FightAction.CAST_MAGIC || type == FightAction.PHYSICAL_ATTACK) {
//            boolean gourdEffect = (Boolean) ArtifactType.GOURD.getEffect().trigger(fight, attacker);
//            if (gourdEffect) {
//                fight.makeTargetArtifactInvalid(attacker.getTargetId());
//                ArtifactType.GOURD.getEffect().broadCast(fight, attacker);
//            }
//        }
//        if(attacker.isPlayer()){
//            LinkedHashMap<String, TitleInfo> titleList = attacker.getRole().getExtendBox().getTitleList();
//            if(titleList != null && titleList.containsKey("试道大会")){
//                if("试道王者".equals(titleList.get("试道大会").getTitle())){
//                    FightMessageService fightMessageService = SpringUtils.getBean(FightMessageService.class);
//                    FightMessageUtil.sendFightPackage(fight, fightMessageService.attackSkillEffect(attacker.getId(), (short)2181, "", 0));
//                }
//
//            }
//        }
        if(attacker.isPlayer()){
            LinkedHashMap<String, TitleInfo> titleList = attacker.getRole().getExtendBox().getTitleList();
            if(titleList != null && titleList.containsKey("试道王者")){
                if("试道王者".equals(titleList.get("试道王者").getTitle())){
                    FightMessageService fightMessageService = SpringUtils.getBean(FightMessageService.class);
                    FightMessageUtil.sendFightPackage(fight, fightMessageService.attackSkillEffect(attacker.getId(), (short)2181, "", 0));
                }

            }
        }
        /** 法攻切换为普通，原因 怪物技能配置里面有物攻的ID **/
        if (type == FightAction.CAST_MAGIC) {

            if (attacker.getSkillId() == FightAction.PHYSICAL_ATTACK) {
                attacker.setType(FightAction.PHYSICAL_ATTACK);
                type = FightAction.PHYSICAL_ATTACK;
            }
        }
        if (type == FightAction.DEFENSE) {// 防御
            defense(attacker, fight);
        } else if (type == FightAction.PHYSICAL_ATTACK) {// 物攻
            normalAttack(attacker, fight);
        } else if (type == FightAction.CAST_MAGIC) {// 法攻
            magicAttack(attacker, fight);
        } else if (type == FightAction.APPLY_ITEM) {// 使用道具
            useItem(attacker, fight);
        } else if (type == FightAction.FLEE) {// 逃跑

            flee(attacker, fight);
        } else if (type == FightAction.SELECT_PET) {// 召唤
            selectPet(attacker, fight);
        } else if (type == FightAction.CATCH_PET) {// 捕捉
            catchPet(attacker, fight);
        } else if (type == FightAction.CALLBACK_PET) {// 召回
            callbackPet(attacker, fight);
        } else if (type == FightAction.ARTIFACT_EXTRA_SKILL) {// 使用法宝特殊技能
            useArtifactSkill(attacker, fight);
        }
    }

    /**
     * 使用法宝特殊技能
     */
    private void useArtifactSkill(FightObject fightObject, Fight fight) {
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), fightObject));// 出手开始

        int specialSkillId = SpringUtils.getArtifactService().getSpecialSkillId(fightObject);
        int specialSkillLevel = SpringUtils.getArtifactService().getSpecialSkillLevel(fightObject);
        log.error("法宝特殊技能ID:[{}],level:[{}],释放技能:id[{}]", specialSkillId, specialSkillLevel,
                fightObject.getSkillId());
        FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(fightObject, 1, 2, 0));

        ArtifactSkillProcessor.getSkillProcessor(specialSkillId).useSkill(fight, fightObject,specialSkillLevel);

        FightMessageUtil.sendFightPackage(fight, fightMessageService.sendFightObjectStatus(fightObject));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(fightObject.getId()));// 出手结束
    }

    /**
     * 检查身上的减益状态
     *
     * @param fight
     * @param fightObject
     * @return
     */
    private boolean checkDeStatus(Fight fight, FightObject fightObject) {
        /** 先判断混乱状态 如果是混乱状态 攻击友方 */
        if (fightObject.isConfusion()) {
            fightObject.setType(2);
            fightObject.setSkillId(0);
            fightObject.setTargetId(0);
            normalAttack(fightObject, fight);
            return true;
        }
        boolean noAction = false;
        /** 中毒状态可以法攻不能物攻 所以不等于法攻的时候才判断 */
        if (fightObject.isPoison()
                && (fightObject.getType() != FightAction.CAST_MAGIC && fightObject.getType() != FightAction.APPLY_ITEM
                || fightObject.getSkillId() == 501)) {
            noAction = true;
        }
        /** 昏睡状态可以使用道具加血 所以不是使用道具就站着不动 */
        if (fightObject.isSleep() && fightObject.getType() != FightAction.APPLY_ITEM) {
            noAction = true;
        }
        /** 遗忘状态 其实有几率物攻出手 可以跟中毒共存 所以放在中毒状态后面 */
        if (fightObject.isForgotten()) {
            noAction = true;
        }
        /** 冰冻 不能做动作 只要有冰冻 所有类型出手都不行 */
        if (fightObject.isFrozen()) {
            noAction = true;
        }
        if (noAction) {
            fightMessageService.sendNullAction(fight, fightObject);
        }
        return noAction;
    }

    /**
     * 战斗开始发送的封包
     */
    public void sendStartCombat(RespCombatFriends respCombatFriends, RespCombatOpponets respCombatOpponets,
                                List<Member> members) {
        for (Member member : members) {
            if (!member.isInTeam()) {
                continue;
            }
            Role tempRole = SpringUtils.getRoleService().getOnlinePlayer(member.getUid());
            if (tempRole == null) {
//                logger.error("战斗开始未找到role=={}", member.getUid());
                continue;
            }

            MessagePusher.pushMessage(tempRole, fightMessageService.startCombat(tempRole));
            MessagePusher.pushMessage(tempRole, fightMessageService.autoFightStatus(tempRole));

            broadcastService.sendTitleInfo(tempRole);


            MessagePusher.pushMessage(tempRole, respCombatFriends);

            MessagePusher.pushMessage(tempRole, respCombatFriends);
            MessagePusher.pushMessage(tempRole, respCombatOpponets);
        }
    }

    private void fireEndEvent(Fight fight, Role role, Pet pet) {
        try {
            if (fight.getData() != null && fight.getData().getBoolean("fight_result_fail", false)) {
                /** 产生一个战斗失败事件 */
                EventDispatcher.getInstance()
                        .fireEvent(new FightEndEvent(fight, EventType.FIGHT_END, role, fight.getId(), FightEndEvent.FAIL,
                                fight.getType(), fight.getBossReward(), fight.getTaskId(), fight.getNpcId(), 0));
                return;
            }
            if (fight.getData() != null && fight.getData().getBoolean("fight_result_success", false)) {
                /** 产生一个战斗胜利事件 */
                EventDispatcher.getInstance()
                        .fireEvent(new FightEndEvent(fight, EventType.FIGHT_END, role, fight.getId(), FightEndEvent.WIN,
                                fight.getType(), fight.getBossReward(), fight.getTaskId(), fight.getNpcId(),
                                pet != null ? pet.getId() : 0));
                return;
            }

            /** 产生战斗结束事件 */
            if (fight.getRound() >= fight.getMaxRound()) {

                /** 产生一个战斗超过最大回合数事件 */
                EventDispatcher.getInstance()
                        .fireEvent(new FightEndEvent(fight, EventType.FIGHT_END, role, fight.getId(), FightEndEvent.MAXROUND,
                                fight.getType(), fight.getBossReward(), fight.getTaskId(), fight.getNpcId(), 0));
                //}
            } else {
                if (fight.isWinner(role.getRoleId())) {
                    /** 产生一个战斗胜利事件 */
                    EventDispatcher.getInstance()
                            .fireEvent(new FightEndEvent(fight, EventType.FIGHT_END, role, fight.getId(), FightEndEvent.WIN,
                                    fight.getType(), fight.getBossReward(), fight.getTaskId(), fight.getNpcId(),
                                    pet != null ? pet.getId() : 0));
                } else {
                    /** 产生一个战斗失败事件 */
                    EventDispatcher.getInstance()
                            .fireEvent(new FightEndEvent(fight, EventType.FIGHT_END, role, fight.getId(), FightEndEvent.FAIL,
                                    fight.getType(), fight.getBossReward(), fight.getTaskId(), fight.getNpcId(), 0));
                }
            }
        } catch (Exception e) {
           // LoggerUtils.error(e.getMessage(), e);
            log.error("退出战斗产生结束事件时报错了,战场ID=[{}],角色名=[{}],错误信息[{}]", fight.getId(), role.getName(), e);
        }
    }

    /**
     * 战斗掉落
     */
    private void fightDrop(Fight fight, Role role) {
//        // TODO 每次战斗胜利都要循环太麻烦了，先这样，后面看怎么优化
//        log.info("战斗胜利，战斗类型："+fight.getType()+"战斗信息的ExpMap:"+fight.getExpMap()+"--------"+fight.getExpMap().getInt("level", 0));
//        List<FightDropSet> fightDropSets = DropDataPool.fightType2DropMap.get(fight.getType());
//        if (fightDropSets == null) {
//            return;
//        }
//        log.info("战斗胜利，组奖品配置："+ JSON.toJSON(fightDropSets));
//       // logger.info("每次战斗胜利都要循环太麻烦了，先这样，后面看怎么优化=={}", Json.toJson(fight, JsonFormat.compact()));
//        for (FightDropSet fightDropSet : fightDropSets) {
//
//            if (fightDropSet.getMinRoleLevel() > 0 && role.getLevel() < fightDropSet.getMinRoleLevel()) {
//                continue;
//            }
//            if (fightDropSet.getMaxMonsterLessValue() > 0) {
//                int monsterLevel = fight.getExpMap() != null ? fight.getExpMap().getInt("level", 0) : 0;
//                if (role.getLevel() - monsterLevel > fightDropSet.getMaxMonsterLessValue()) {
//                    continue;
//                }
//            }
//            String monsterName = getMonsterName(fight);
//            ThreadLocalUtil.addLocalTask(role, () -> {
//                role.pushTempCache("drop_monster_name", monsterName);
//                SpringUtils.getDropService().drop(role, fightDropSet.getDropGroup());
//                role.popTempCache("drop_monster_name");
//            });
//        }
    }
    private String getMonsterNameByType(int type) {
        switch (type) {
            case Const.fightType_monster:
                return "野怪";
            case Const.fightType_shanggu:
                return "上古妖王";
            case Const.fightType_wannian:
                return "万年老妖";
            case Const.fightType_yanhuan_nianshou:
                return "北海烟花";
            case Const.fightType_bianyixingun:
                return "变异星君";
            case Const.getFightType_Taoliulinshagui:
                return "地府冤魂";
            case Const.fightType_Zhengyaotaoyaoguai:
                return "镇妖塔妖怪";
            case Const.tiandi:
                return "天帝";
            case Const.tianleizhenzi:
                return "雷震子";
            case Const.tianlijing:
                return "李靖";
            case Const.tiantaibai:
                return "太白";
            case Const.tiankongxuan:
                return "孔宣";
            case Const.tiannezha:
                return "哪吒";
            case Const.tianyangjian:
                return "杨戬";
            case Const.fightType_Alienintrusion:
                return "异族";
            case Const.fightType_Undergroundrebels:
                return "地府叛逆";
            case Const.fightType_daysoldier:
                return "天界叛逆";
            case Const.fightType_elves:
                return "精灵";
            case Const.darijinwu:
                return "大日金乌";
            case Const.shalu:
                return "杀戮大帝";
            case Const.xieling:
                return "邪灵大帝";
            case Const.zhenwu:
                return "真武大帝";
            case Const.jiuyou:
                return "九幽大帝";
            case Const.molongtuntian:
                return "魔龙吞天";
            case Const.molongtuntian2:
                return "二星魔龙吞天";
            case Const.molongzhizhua:
                return "魔龙之爪";
            case Const.molongzhizhua2:
                return "二星魔龙之爪";
            case Const.molongzhishou:
                return "魔龙之首";
            case Const.molongzhiyan:
                return "魔龙之眼";
            case Const.molongzhiwei:
                return "魔龙之尾";
            case Const.molongzhishou2:
                return "二星魔龙之首";
            case Const.molongzhiyan2:
                return "二星魔龙之眼";
            case Const.molongzhiwei2:
                return "二星魔龙之尾";
            case Const.jiutian:
                return "九天真君";
            case Const.fightType_qisha:
                return "七杀星君";
            case Const.fightType_lymy:
                return "炼狱冥炎";
            case Const.fightType_lymy2:
                return "二星炼狱冥炎";
            case Const.fightType_tianbingshenjiang:
                return "怪物攻城";
            case Const.kuangshi:
                return "攻城一星百年狂狮怪";
            case Const.baigu:
                return "攻城八星白骨精";
            case Const.baihua:
                return "攻城五星百花羞";
            case Const.ciwei:
                return "攻城二星百年刺猬精";
            case Const.xiangjing:
                return "攻城四星百年象精";
            case Const.zhuyao:
                return "攻城三星百年猪妖";
            case Const.kongque:
                return "攻城九星孔雀妖姬";
            case Const.luocha:
                return "攻城十星罗刹王";
            case Const.niumo:
                return "攻城六星牛魔王";
            case Const.yecha:
                return "攻城七星夜叉王";
            case Const.luobotaozi://萝卜桃子
                return "萝卜桃子怪物";
            case Const.mijing://萝卜桃子
                return "奇门秘境挑战";
            case Const.fightType_zhanShen:
                return "战神";
//            case Const.fightType_xiufa:
//                return "修法";
            case Const.fightType_partyDaily:
                return "帮派日常";
            case Const.fightType_xing:
                return "天地星";
            case Const.fightType_pirate:
                return "海盗";
            case Const.fightType_superboss:
                return "超级BOSS";
            case Const.fightType_caiShen:
                return "财神";
            case Const.fightType_fuxing:
                return "福星";
            case Const.shidi:
                return "戾天穷奇";
            case 200:
                return "八仙";

            default:
                return "怪物";
        }
    }
    /**
     * 获得怪物的名称
     */
    private String getMonsterName(Fight fight) {
        return getMonsterNameByType(fight.getType());
    }


    /**
     * 检测开启驱魔香
     */
    public void checkOpenAvoidMonster(Role role) {
        if (!role.isAvoidMonster()) {
            role.setConfirm(new AvoidMonsterConfirm(true));
            String tips = I18nIdDataPool.getI18nContent(I18nId.PMT_900);
            RespConfirm respConfirm = new RespConfirm();
            respConfirm.setTips(tips);
            MessagePusher.pushMessage(role, respConfirm);
        }
    }

    /**
     * 开启驱魔香
     */
    public void openAvoidMonster(Role role) {
        RespMsg respMsg = new RespMsg();
        RespGeneralNotify respGeneralNotify = new RespGeneralNotify();
        respGeneralNotify.setNotify((short) NotifyModules.NOTIFY_EXORCISM_STATUS);
        role.setAvoidMonster(true);
        respGeneralNotify.setValue("1");
        respMsg.setMsg(I18nIdDataPool.getI18nContent(I18nId.PMT_901));

        MessagePusher.pushMessage(role, respGeneralNotify);
        MessagePusher.pushMessage(role, respMsg);
    }

    /**
     * 关闭驱魔香
     */
    public void closeAvoidMonster(Role role) {
        RespMsg respMsg = new RespMsg();
        RespGeneralNotify respGeneralNotify = new RespGeneralNotify();
        respGeneralNotify.setNotify((short) NotifyModules.NOTIFY_EXORCISM_STATUS);
        role.setAvoidMonster(false);
        respGeneralNotify.setValue("0");
        respMsg.setMsg(I18nIdDataPool.getI18nContent(I18nId.PMT_902));

        MessagePusher.pushMessage(role, respGeneralNotify);
        MessagePusher.pushMessage(role, respMsg);
    }

    public void sendQiMiSkills(Role role, int newPet) {
        int lastPet = role.getLastQinMiPet();
        if (lastPet > 0 && lastPet != newPet) {
            Pet pet = role.getPetBox().getPetByPetId(lastPet);
            if (pet != null) {
                ArrayList<SkillInfo> skillInfos = new ArrayList<>();
                RespUpdateSkill respUpdateSkill = new RespUpdateSkill();
                respUpdateSkill.setId(role.getRoleId());
                for (Map.Entry<Integer, RoleSkill> entry : pet.getSkillBox().getSkills().entrySet()) {
                    RoleSkill petSkill = entry.getValue();
                    if (!PetDataPool.isInnateSkill(petSkill.getName()) && !PetDataPool.isDevelopSkill(petSkill.getName())) {continue;}

                    SkillInfo skillInfo = skillService.getSkillInfo(petSkill, 0);
                    skillInfos.add(skillInfo);
                }
                respUpdateSkill.setList(skillInfos);
                MessagePusher.pushMessage(role, respUpdateSkill);
            }
        }

        if (newPet > 0) {
            List<RoleSkill> roleSkillList = role.getSkillBox().queryAllSkills();
            RespUpdateSkill respUpdateSkill = new RespUpdateSkill();
            respUpdateSkill.setId(role.getRoleId());
            ArrayList<SkillInfo> skillInfos = new ArrayList<>();
            List<Integer> skillIds = new ArrayList<>();
            for (RoleSkill roleSkill : roleSkillList) {
                if (skillIds.contains(roleSkill.getSkillId())) {continue;}
                skillIds.add(roleSkill.getSkillId());
                skillInfos.add(skillService.getSkillInfo(roleSkill, role.getExtraSkillLevel()));
            }

            // 法宝特殊技能    --亲密无间
            ArtifactService artifactService = SpringUtils.getBean(ArtifactService.class);
            int skillId = artifactService.getSpecialSkillId(role);
            if (skillId == SkillConst.SKILL_QIN_MI) {
                Pet pet = role.getPetBox().getPetByPetId(newPet);
                if (pet != null) {
                    for (Map.Entry<Integer, RoleSkill> entry : pet.getSkillBox().getSkills().entrySet()) {
                        RoleSkill petSkill = entry.getValue();
                        /**宠物技能与人物技能一致时，则保留人物的*/
                        if (skillIds.contains(petSkill.getSkillId())) {continue;}
                        skillIds.add(petSkill.getSkillId());

                        /**只分享天生技能和研发技能给人物用*/
                        if (!PetDataPool.isInnateSkill(petSkill.getName()) && !PetDataPool.isDevelopSkill(petSkill.getName())) {continue;}

                        SkillInfo skillInfo = skillService.getSkillInfo(petSkill, 0);
                        skillInfo.setIsTempSkill((byte) 1);
                        skillInfos.add(skillInfo);
                    }
                }
                role.setLastQinMiPet(newPet);
            }

            respUpdateSkill.setList(skillInfos);
            MessagePusher.pushMessage(role, respUpdateSkill);
        }

    }

    /**
     * 检测帮派日常猜正假且使用法术技能时不用使用
     */
    public boolean canProcessSkill(Role role, Fight fight, int skillId) {
        if (fight != null && fight.getData() != null && fight.getData().getBoolean("fight_guess_true", false)
                && skillId != 2) {
            MessagePusher.pushMessage(role, new RespMsg("本技能不能作用在该对象上"));
            return false;
        }
        return true;
    }

    /**
     * 检测帮派日常猜正假 是否胜利
     */
    private void checkGuessSuccess(Fight fight) {
        /** 猜真假，有1个死亡时，则胜利 */
        if (fight.getData() != null && fight.getData().getBoolean("fight_guess_true", false)) {
            fight.getData().setv("fight_result_success", true);
        }
    }

    /**
     * 检测目标 是否匹配帮派日常顺序打倒目标对象，匹配时则设置目标死亡
     */
    private void checkOrderTarget(Fight fight, List<Integer> targetList) {
        if (fight.getData() != null && fight.getData().getBoolean("fight_order_target", false)) {
            String targetName = null;
            List<String> names = fight.getData().getAsList("fight_order_target_name", String.class);
            List<String> deadNames = fight.getData().getAsList("fight_order_target_dead_name", String.class);
            if (names.size() > deadNames.size()) {
                targetName = names.get(deadNames.size());
            }

            for (int targetId : targetList) {
                FightObject fightTarget = fight.queryFightObject(targetId);
                if (fightTarget.getName().equals(targetName)) {
                    /** 目标死亡 */
                    fightTarget.setCurrLife(0);
                    deadNames.add(targetName);

                    /** 所有目标都死亡时，则胜利 */
                    if (names.size() == deadNames.size()) {
                        fight.getData().setv("fight_result_success", true);
                        break;
                    }
                }
            }
        }
    }
    //指定对象喊话，就喊一次。
    public void newCheckRoundShouting(Fight fight, Role role) {
        if (fight.getData() == null) {
            return;
        }
        //所有喊话
        List<String> roundStartTips = fight.getData().getAsList("fight_round_start_shouting", String.class);
        if (roundStartTips == null || roundStartTips.size() == 0) {
            return;
        }
//        int roundStartShoutingPeriod = fight.getData().getInt("fight_round_start_shouting_period", 0);
//        if (roundStartShoutingPeriod > 0 && fight.getRound() != roundStartShoutingPeriod ) {
//            return;
//        }
        List<FightObject> tempMemberListB = new ArrayList<>(fight.getListB());
        //所有喊话对象
        List<Integer> fightObjectId = fight.getData().getAsList("fight_round_start_shouting_fightobject", Integer.class);
        
        if(fightObjectId.size()>0){
            for (int i = 0; i < fightObjectId.size(); i++) {
                int id = fightObjectId.get(i);
                for (FightObject fightObject : tempMemberListB) {
                    if(fightObject.getId() == id){
                        String shouting = roundStartTips.get(i);
                        Message message = SpringUtils.getBean(FightMessageService.class).fightToMsg(fightObject, shouting);
                        MessagePusher.pushMessage(role,message);
                    }
                }
            }
        }
        //清空喊话
        fight.getData().setv("fight_round_start_shouting_fightobject",Arrays.asList());
    }

//    public static void main(String[] args) {
//        Fight2 fight = new Fight2();
//        if (fight.getData() == null) {
//            fight.setData(new NutMap());
//        }
//        fight.setRound(1);
//        fight.getData().setv("fight_round_start_shouting", Arrays.asList("1","2"));
//        fight.getData().setv("fight_round_start_shouting_period", 1);
//        fight.getData().setv("fight_round_start_shouting_fightobject",Arrays.asList(555,444));
//        //所有喊话
//        List<String> roundStartTips = fight.getData().getAsList("fight_round_start_shouting", String.class);
//        if (roundStartTips == null || roundStartTips.size() == 0) {
//            return;
//        }
//        int roundStartShoutingPeriod = fight.getData().getInt("fight_round_start_shouting_period", 0);
//        if (roundStartShoutingPeriod > 0 && fight.getRound() != roundStartShoutingPeriod ) {
//            return;
//        }
//        List<FightObject> tempMemberListB = new ArrayList<>(fight.getListB());
//        FightObject fightObject =  new FightObject();
//        fightObject.setId(555);
//        tempMemberListB.add(fightObject);
//        FightObject fightObject2 =  new FightObject();
//        fightObject2.setId(444);
//        tempMemberListB.add(fightObject2);
//        //所有喊话对象
//        List<Integer> fightObjectId = fight.getData().getAsList("fight_round_start_shouting_fightobject", Integer.class);
//
//        if(fightObjectId.size()>0){
//            for (int i = 0; i < fightObjectId.size(); i++) {
//                int id = fightObjectId.get(i);
//                for (FightObject fightObj : tempMemberListB) {
//                    if(fightObj.getId() == id){
//                        System.out.println("对象:"+id+"说话："+roundStartTips.get(i));
//                    }
//                }
//            }
//        }
//    }
    /**
     * 检测回合，让对立方喊话
     */
    public void checkRoundShouting(Fight fight, Role role) {
        if (fight.getData() == null) {
            return;
        }
        List<Integer> fightObjectId = fight.getData().getAsList("fight_round_start_shouting_fightobject", Integer.class);

        if(fightObjectId != null && fightObjectId.size()>0){
            newCheckRoundShouting( fight,  role);
            return ;
        }
        List<String> roundStartTips = fight.getData().getAsList("fight_round_start_shouting", String.class);
        if (roundStartTips == null || roundStartTips.size() == 0) {
            return;
        }
        int roundStartShoutingPeriod = fight.getData().getInt("fight_round_start_shouting_period", 0);
        if (roundStartShoutingPeriod > 0 && fight.getRound() % roundStartShoutingPeriod != 0) {
            return;
        }

        int remainRound = fight.getRound() == 0 ? fight.getMaxRound() : fight.getMaxRound() - fight.getRound() + 1;
        boolean fightRefreshShouTing = fight.getData().getBoolean("fight_npc_boss_refresh",false);
        if(fightRefreshShouTing){
            String name = fight.getData().getString("fight_npc_boss_refresh_name","");
            if("财神".equals(name)){
                Map map = new HashMap();
                List<FightObject> tempMemberListB = new ArrayList<>(fight.getListB());
                for (FightObject fightObject : tempMemberListB) {
                    String msg = "";
                    if("宠物狗".equals(fightObject.getName()) && !map.containsKey(fightObject.getName())){
                        msg = "我是财神的爱宠，千万不要伤到我！";
                        map.put("宠物狗","1");
                    }
                    if("财气猪".equals(fightObject.getName())  && !map.containsKey(fightObject.getName())){
                        msg = "我是看管钱袋子的，打我没好处！";
                        map.put("财气猪","1");
                    }
                    if("精灵鼠".equals(fightObject.getName())  && !map.containsKey(fightObject.getName())){
                        msg = "不要打我啊，我真的没有宝贝啊！";
                        map.put("精灵鼠","1");
                    }
                    if("财神".equals(fightObject.getName())){
                        boolean fight_npc_boss_angry = fight.getData().getBoolean("fight_npc_boss_angry", false);
                        if(fight_npc_boss_angry){
                            msg = "竟然敢打我的爱宠，我很生气！";
                        }else{
                            msg = "讨厌的#Y精灵鼠#n又来了，快消灭它！小心不要误伤到我的爱宠！";
                        }
                    }
                    if(StringUtils.isNotEmpty(msg)){
                        Message message = SpringUtils.getBean(FightMessageService.class).fightToMsg(fightObject, msg);
                        MessagePusher.pushMessage(role,message);
                    }

                }
            }else if("福星".equals(name)){
                List<FightObject> tempMemberListB = new ArrayList<>(fight.getListB());
                for (FightObject fightObject : tempMemberListB) {
                    if("福星".equals(fightObject.getName())){
                        String msg = "";
                        if( fight.getData().containsKey("fight_npc_boss_angry")){
                            if(fight.getData().getBoolean("fight_npc_boss_angry")){
                                //胜利
                                msg = "#G游戏第"+(fight.getRound()-1)+"回合，成功！#n";
                            }else{
                                //失败
                                msg = "#R游戏第"+(fight.getRound()-1)+"回合，失败！#n";
                            }
                        }else{
                            //第一回合
                            msg = "把#Y狐狸#n和#Y野狗#n的数量变成一样（狐狸、野狗数量不能为0）,你就得奖";
                        }
                        Message message = SpringUtils.getBean(FightMessageService.class).fightToMsg(fightObject, msg);
                        MessagePusher.pushMessage(role,message);
                    }
                }
            }
        }else{
            if (roundStartTips.size() > 1) {
                /** 多个喊话时，对立方战斗对象随机喊话 */
                ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
                List<FightObject> tempMemberListB = new ArrayList<>(fight.getListB());
                for (String tip : roundStartTips) {
                    if (tempMemberListB.size() == 0) {
                        break;
                    }

                    int tempIndex = threadLocalRandom.nextInt(tempMemberListB.size());
                    FightObject tempObject = tempMemberListB.remove(tempIndex);
                    String shouting = String.format(tip, remainRound);
                    Message message = SpringUtils.getBean(FightMessageService.class).fightMsg(tempObject, shouting);
                    SpringUtils.getTeamService().pushMessage(role, message);
                }
            } else {
                /** 只有1个喊话时，第1个对立方战斗对象喊话 */
                FightObject fightObject = fight.getListB().get(0);
                String shouting = String.format(roundStartTips.get(0), remainRound);
                Message message = SpringUtils.getBean(FightMessageService.class).fightToMsg(fightObject, shouting);
                MessagePusher.pushMessage(role,message);
            }
        }
    }

    /**
     * 战斗中是否有超级boss阵魄存在
     */
    public boolean isHasSuperBossZP(Fight fight) {
        if (fight == null) {
            return false;
        }
        if (fight.getListB() == null) {
            return false;
        }
        for (FightObject fightObject : fight.getListB()) {
            if (fightObject.isSuperBossZP()) {
                return true;
            }
        }

        return false;
    }

    /**
     * 战斗中是否有超级boss阵魄减伤存在
     */
    public boolean isHasSuperBossZPJS(Fight fight) {
        if (fight == null) {
            return false;
        }
        if (fight.getListB() == null) {
            return false;
        }
        for (FightObject fightObject : fight.getListB()) {
            if (fightObject.isSuperBossZPJS()) {
                return true;
            }
        }

        return false;
    }

    /**
     * 强制PK战斗
     *
     * @param listA
     * @param listB
     * @param role
     */
    public void enterTeamForcePK(List<Member> listA, List<Member> listB, Role role) {
        if (canFight(role, listA) == false) {
            return;
        }
        if (canFight(role, listB) == false) {
            return;
        }
        if (teamService.isInTeamAndNotLeader(role)) {
//            logger.info("{}({})不是队长触发战斗", role.getUid(), role.getName());
            return;
        }

        int mapId = role.getPos().getMapId();
        Fight battleground = FightFactory.getFightFactory(Const.fightType_forcePK).create(mapId, Const.fightType_forcePK, listA, listB);
        /**最多150回合*/
        battleground.setMaxRound(Const.FORCEPK_MAX_ROUND);
        battleground.start();
    }

    public void addLook(int roleId,int lookId){
        FightExecutorService.roleId_lookonRoleId.put(roleId,lookId);
    }

    public void delLook(int roleId){
        FightExecutorService.roleId_lookonRoleId.remove(roleId);
    }
    public boolean isOnLook(int roleId){
        return FightExecutorService.roleId_lookonRoleId.get(roleId) != null;
    }


}
